SpringMVC结合REST

一、什么是REST
REST即 Representational State Transfer,也就是(资源)表现层状态转化。资源是指网络上的一个实体或者说是网络上的一个具体信息。 每种资源对应一个特定的URI,因此URI为每一个资源的独一无二的识别符。状态转化指的是每发出一个请求,就代表了客户端和服务器端的一次交互过程。HTTP协议是一个无状态协议,即所有的状态都保存在服务器上。因此用户想要操作服务器,必须通过某种手段,让服务器发生状态变化。而这种状态变化是建立在表现层之上的,所以就是“表现层状态变化”。
具体的说,就是HTTP协议里面四个表示操作的方法:
1、GET : 用来获取资源 ; 
2、POST : 用来新建资源 ; 
3、PUT : 用来更新资源 ; 
4、DELETE : 用来删除资源 。

二、SpringMVC结合REST
因为浏览器的form表单只支持GET与POST请求,因此只通过浏览器无法完成REST的操作。而Spring3.0增加了一个过滤器,可以将这些HTTP请求(GET或者POST)转换为标准的HTTP方法,使得Spring支持GET、POST、PUT与DELETE四种请求。
这个过滤器就是HiddenHttpMethodFilter。
其源码如下:
public class HiddenHttpMethodFilter extends OncePerRequestFilter {


    /** Default method parameter: {@code _method} */
    public static final String DEFAULT_METHOD_PARAM = "_method";


    private String methodParam = DEFAULT_METHOD_PARAM;




    /**
     * Set the parameter name to look for HTTP methods.
     * @see #DEFAULT_METHOD_PARAM
     */
    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {


        String paramValue = request.getParameter(this.methodParam);
        if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
            String method = paramValue.toUpperCase(Locale.ENGLISH);
            HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
            filterChain.doFilter(wrapper, response);
        }
        else {
            filterChain.doFilter(request, response);
        }
    }
//...

从上面的源码可以看出,当request.getMethod() 等于POST 且 通过String paramValue = request.getParameter(this.methodParam); 得到的paramValue不为null 或空,那么将执行对应的paramValue方法。
要使用HiddenHttpMethodFilter过滤器,需要在web.xml作如下配置:
web.xml
<filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>


<filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
1、处理GET请求
浏览器默认支持GET请求,在REST中用来获取资源。在JSP页面中不需要使用隐藏域。例如:
<a href="testRest/1">Test Rest Get</a>
与之对应的后台处理代码:
    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
    public String testRest(@PathVariable Integer id) {
        System.out.println("testRest GET: " + id);
        return SUCCESS;
    }

2、处理POST请求
浏览器默认支持POST请求,在REST中用来新建资源。在JSP页面中不需要使用隐藏域。例如:
<form action="testRest" method="post">
        <input type="submit" value="TestRest POST"/>
</form>
与之对应的后台处理代码:
    @RequestMapping(value = "/testRest", method = RequestMethod.POST)
    public String testRest() {
        System.out.println("testRest POST");
        return SUCCESS;
    }
3、处理PUT请求
浏览器不支持PUT请求,在REST中用来更新资源。在JSP页面中需要使用隐藏域。例如:
   <form action="testRest/1" method="post">
        <input type="hidden" name="_method" value="PUT"/>
        <!--设置隐藏域 注意 name必须是"_method",而value是请求类型-->
        <input type="submit" value="TestRest PUT"/>
    </form>
与之对应的后台处理代码:SpringMVC自动用_method对应的value来取代原来的POST方法。
    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
    public String testRestPut(@PathVariable("id") Integer id) {
        System.out.println("testRest Put: " + id);
        return SUCCESS;
    }

4、处理DELETE请求
浏览器不支持DELETE请求,在REST中用来删除资源。在JSP页面中需要使用隐藏域。例如:
   <form action="testRest/1" method="post">
        <input type="hidden" name="_method" value="DELETE"/>
        <!--设置隐藏域 注意 name必须是"_method",而value是请求类型-->
        <input type="submit" value="TestRest DELETE"/>
    </form>
与之对应的后台处理代码:SpringMVC自动用_method对应的value来取代原来的POST方法。
    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
    public String testRestDELETE(@PathVariable("id") Integer id) {
        System.out.println("testRest Put: " + id);
        return SUCCESS;
    }

三、Spring通过POST方法出现中文乱码
解决方案:使用Spring的字符过滤器。
web.xml作如下配置:
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>  
            <param-name>forceEncoding</param-name>  
            <param-value>true</param-value>  
        </init-param> 
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

注意要把这个过滤器放在所有过滤器中最前方,保证先进性字符过滤。例如可以紧接着放在springdispatcherServlet下。


posted on 2017-03-28 20:18  想作会飞的鱼  阅读(246)  评论(0编辑  收藏  举报

导航