zoukankan      html  css  js  c++  java
  • SpringMVC(四):@RequestMapping结合org.springframework.web.filter.HiddenHttpMethodFilter实现REST请求

    1)REST具体表现:

    --- /account/1  HTTP GET       获取id=1的account

    --- /account/1  HTTP DELETE 删除id=1的account

    --- /aacount/1  HTTP PUT        更新id=1的account

    --- /account      HTTP POST     新增account

    2)SpringMVC中如何实现REST?

    众所周知,浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持。Spring3.0增加了一个过滤器,可以将这些请求转化为标准的http方法,使得支持GET、POST、PUT及DELETE请求。

    这个过滤器就是:org.springframework.web.filter.HiddenHttpMethodFilter

     1 package org.springframework.web.filter;
     2 
     3 import java.io.IOException;
     4 import java.util.Locale;
     5 import javax.servlet.FilterChain;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletRequestWrapper;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 import org.springframework.util.Assert;
    12 import org.springframework.util.StringUtils;
    13 import org.springframework.web.util.WebUtils;
    14 
    15 /**
    16  * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods,
    17  * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only
    18  * support GET and POST, a common technique - used by the Prototype library, for instance -
    19  * is to use a normal POST with an additional hidden form field ({@code _method})
    20  * to pass the "real" HTTP method along. This filter reads that parameter and changes
    21  * the {@link HttpServletRequestWrapper#getMethod()} return value accordingly.
    22  *
    23  * <p>The name of the request parameter defaults to {@code _method}, but can be
    24  * adapted via the {@link #setMethodParam(String) methodParam} property.
    25  *
    26  * <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart
    27  * POST request, due to its inherent need for checking a POST body parameter.</b>
    28  * So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter}
    29  * <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain.
    30  *
    31  * @author Arjen Poutsma
    32  * @author Juergen Hoeller
    33  * @since 3.0
    34  */
    35 public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    36 
    37     /** Default method parameter: {@code _method} */
    38     public static final String DEFAULT_METHOD_PARAM = "_method";
    39 
    40     private String methodParam = DEFAULT_METHOD_PARAM;
    41 
    42 
    43     /**
    44      * Set the parameter name to look for HTTP methods.
    45      * @see #DEFAULT_METHOD_PARAM
    46      */
    47     public void setMethodParam(String methodParam) {
    48         Assert.hasText(methodParam, "'methodParam' must not be empty");
    49         this.methodParam = methodParam;
    50     }
    51 
    52     @Override
    53     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    54             throws ServletException, IOException {
    55 
    56         HttpServletRequest requestToUse = request;
    57 
    58         if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
    59             String paramValue = request.getParameter(this.methodParam);
    60             if (StringUtils.hasLength(paramValue)) {
    61                 requestToUse = new HttpMethodRequestWrapper(request, paramValue);
    62             }
    63         }
    64 
    65         filterChain.doFilter(requestToUse, response);
    66     }
    67 
    68 
    69     /**
    70      * Simple {@link HttpServletRequest} wrapper that returns the supplied method for
    71      * {@link HttpServletRequest#getMethod()}.
    72      */
    73     private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
    74 
    75         private final String method;
    76 
    77         public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
    78             super(request);
    79             this.method = method.toUpperCase(Locale.ENGLISH);
    80         }
    81 
    82         @Override
    83         public String getMethod() {
    84             return this.method;
    85         }
    86     }
    87 
    88 }

    从这个filter代码中可以得知,该filter是通过POST方式提交表单,该表单中包含一个名称为_method的隐藏域,该隐藏域的值用来判定将要转化的请求方式。所谓的转化请求方式,就是在该filter中重新生成了一个新的、标准化的请求。

    3)如何使用到springmvc项目中?

    步骤一:在web.xml中添加filter配置:

        <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>

    步骤二:在HelloWord.java中添加get/post/put/delete方法:

     1 package com.dx.springlearn.handlers;
     2 
     3 import org.springframework.stereotype.Controller;
     4 import org.springframework.web.bind.annotation.PathVariable;
     5 import org.springframework.web.bind.annotation.RequestMapping;
     6 import org.springframework.web.bind.annotation.RequestMethod;
     7 
     8 @Controller
     9 @RequestMapping("class_requestmapping")
    10 public class HelloWord {
    11     private static String SUCCESS = "success";
    12 
    13     @RequestMapping(value = "/accountDelete/{id}", method = RequestMethod.DELETE)
    14     public String accountDelete(@PathVariable("id") Integer id) {
    15         System.out.println("test rest DELETE,account id:" + id);
    16         return SUCCESS;
    17     }
    18 
    19     @RequestMapping(value = "/accountPut/{id}", method = RequestMethod.PUT)
    20     public String accountPut(@PathVariable("id") Integer id) {
    21         System.out.println("test rest PUT,account id:" + id);
    22         return SUCCESS;
    23     }
    24 
    25     @RequestMapping(value = "/account", method = RequestMethod.POST)
    26     public String account() {
    27         System.out.println("test rest POST");
    28         return SUCCESS;
    29     }
    30 
    31     @RequestMapping(value = "/account/{id}", method = RequestMethod.GET)
    32     public String account(@PathVariable("id") Integer id) {
    33         System.out.println("test rest GET,account id:" + id);
    34         return SUCCESS;
    35     }
    36 }

    步骤三:在index.jsp中添加get/post/put/delete方法请求的html脚本:

        <!-- delete提交 -->    
        <form id="form_testRestMethod_DELETE" name="form_testRestMethod_DELETE" method="POST"
            action="class_requestmapping/accountDelete/2">
            <input type="hidden" name="_method" value="DELETE" />
            <button name="submit" id="submit">test rest DELETE</button>
        </form>
        <br>
        <!-- put提交 -->    
        <form id="form_testRestMethod_PUT" name="form_testRestMethod_PUT" method="POST"
            action="class_requestmapping/accountPut/2">
            <input type="hidden" name="_method" value="PUT" />
            <button name="submit" id="submit">test rest PUT</button>
        </form>
        <br>
        <!-- post提交 -->    
        <form id="form_testRestMethod_POST" name="form_testRestMethod_POST"
            method="POST" action="class_requestmapping/account">
            <button name="submit" id="submit">test rest POST</button>
        </form>
        <br>
        <!-- get提交 -->    
        <a href="class_requestmapping/account/1">test rest GET</a>
        <br>

    步骤四:测试打印结果为:

    test rest GET,account id:1
    test rest POST
    test rest PUT,account id:2
    test rest DELETE,account id:2

  • 相关阅读:
    团队冲刺二(6)
    团队冲刺二(5)
    JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结
    解决ADB server didn't ACK问题,连上手机问题
    ADB server didn't ACK
    android错误
    Andy
    在Eclipse下搭建Android开发环境教程
    VM VirtualBox 安装 Android 4.3虚拟机完整教程
    电脑安装Android4.0虚拟机的做法
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/8194386.html
Copyright © 2011-2022 走看看