可以的,这很RESTful
前言
RESTful架构,目前越来越火了,以前很多种URL规定,因他而产生了变化,说不定这也是SpringMVC渐渐取代Struts2的原因之一吧。
REST指的是Representaional State Transfer,表现层状态转化。符合REST原则的架构都可以称为RESTful架构。
其实,简单来说就是你写的每个URL都是一种资源:
比如说:
http://blog.youkuaiyun.com/cjm812752853/article/details/52170611
这个URL就表示http://blog.youkuaiyun.com这个网址下cjm812752853这一个用户的编号为52170611的article的details。
因此,所有很RESTful的框架的URL都是一种资源,所以是名词的URL。那这就有问题了,名词?那具体的操作呢,我怎么知道他要对资源做什么操作,增删改查?
因此,这里又不得不提到一个新的名词,状态转化。状态转化,指的就是客户端和服务端互动的一个过程,客户端向服务端提交的HTTP请求方式,比如说,GET、POST、PUT、DELETE 等等。他表示对资源的四种操作,GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
这就够了。
代码
在对Spring的学习中,我渐渐理解了一些操作的原理,所以我就模仿Spring做了一个小小的视图控制类。
基本思路是这样的,创建一个MyBaseServlet,在这个类中,覆盖他的service方法(public)实现路径的控制,然后子类都要继承这个父类。额是不是很有代码入侵性。
所有代码如下:
MyBaseServlet
package com.chen.util;
import com.chen.annocation.RequestMapping;
import com.chen.enums.RequestMethod;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static javafx.scene.input.KeyCode.R;
/**
* Created by CHEN on 2016/8/12.
*/
public class MyBaseServlet extends HttpServlet {
private static final String REDIRECT = "redirect:";
private static final String FORWARD = "forward:";
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String url = req.getRequestURI();
//获得所有的方法
//假如没有二级路径或二级以上的路径就会跳到一级路径
String requestURL = url.substring(url.lastIndexOf("/"));
if (requestURL == null || "".equals(requestURL)) {
//假如没有该方法 就要设置一个默认的方法
requestURL = "";
}
try {
/*注释说明:说真的一开始就没打算玩这么大,没打算做那么多个注解,可是,好像上了贼船,只好做了。
下面这段代码的意思是:找到某个注解,看看他的httpMethod是什么,然后就调用路径的方法,可是这样不够restful.
//获得请求的http方式
String httpMethod = req.getMethod();
// Method[] methods=this.getClass().getMethods(methodStr,HttpServletRequest.class,HttpServletResponse.class);
Method[] methods = this.getClass().getMethods();
String returnURL = "/";
for (Method m : methods) {
//获得注解的内容
RequestMapping mapping = m.getDeclaredAnnotation(RequestMapping.class);
RequestMethod requestMethod = mapping.method();
if (requestMethod==RequestMethod.valueOf(httpMethod)) {
returnURL = (String) m.invoke(this, req, resp);
break;
}
}*/
//
//获得请求的http方式
String httpMethod = req.getMethod();
//获得所有的方法
Method[] methods = this.getClass().getMethods();
String returnURL = "/";
for (Method m : methods) {
//获得注解的内容
RequestMapping mapping = m.getDeclaredAnnotation(RequestMapping.class);
//请求http方式
RequestMethod requestMethod = mapping.method();
//url路径
String methodURL=mapping.value();
if (requestMethod==RequestMethod.valueOf(httpMethod)&&requestURL.equals(methodURL)) {
returnURL = (String) m.invoke(this, req, resp);
break;
}
}
//重定向
if (returnURL.startsWith(REDIRECT)) {
resp.sendRedirect(returnURL.substring(REDIRECT.length()));
return;
} else if (returnURL.startsWith(FORWARD)) {
req.getRequestDispatcher(returnURL.substring(FORWARD.length())).forward(req, resp);
return;
} else {
String rootURL = this.getClass().getResource("/").getPath();
String realURL = InternalResourceViewResolver.getRealURL(rootURL, returnURL);
req.getRequestDispatcher(realURL).forward(req, resp);
return;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
InternalResourceViewResolver
package com.chen.util;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Iterator;
import static com.sun.deploy.security.ruleset.DRSResult.Type.RUN;
/**
* Created by CHEN on 2016/8/12.
* 这是一个视图控制类
* 主要做的就是从jsp_view.xml中获得路径前缀和后缀
* 然后拼接,跳转
*/
public class InternalResourceViewResolver {
public static String getRealURL(String rootURL,String url){
SAXReader reader = new SAXReader();
Document document = null;
try {
document=reader.read(new File(rootURL,"jsp_view.xml"));
} catch (DocumentException e) {
System.out.println("文件不存在");
e.printStackTrace();
}
if(null==document) {
//TODO 很多代码
} else {
//开始读取xml
String prefix=null;
String suffix=null;
//读取文档
Element bean =document.getRootElement();
Iterator<Element> iterator=bean.elementIterator("property");
Element e=null;
while(iterator.hasNext()) {
e= iterator.next();
if("prefix".equals(e.attributeValue("name"))) {
prefix=e.attributeValue("value");
} else if("suffix".equals(e.attributeValue("name"))) {
suffix=e.attributeValue("value");
}
}
StringBuffer string=new StringBuffer(prefix);
string.append(url);
string.append(suffix);
return string.toString();
}
return "";
}
}
RequestMapping
package com.chen.annocation;
import com.chen.enums.RequestMethod;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by CHEN on 2016/8/12.
* 这是一个注解类,用来注解servlet
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
RequestMethod method() default RequestMethod.GET;
String value() default "/";
}
RequestMethod
package com.chen.enums;
/**
* Created by CHEN on 2016/8/12.
* http请求方式
*/
public enum RequestMethod {
GET,HEAD,POST,DELETE,PUT
}
后言
其实这算是一个很简单的Demo了,还缺用户的那些信息之类的,比如说http://blog.youkuaiyun.com/cjm812752853/article/details/52170611中的cjm812752853和52170611还没有实现,但是我觉得,写到这里也就差不多了。
这个用户信息路径值的简单思路应该是这样的(个人想法),把所有的方法value值拿到,然后拿到{}中的请求参数,然后获得相应的值,然后补上去,然后对比。对比一样的,那就是这些方法了。顺带的,可以使用ModelDriven之类的机制构造对象。
如果你有任何疑问,欢迎留言交流。