Spring MVC 学习手记(3)- HiddenHttpMethodFilter 过滤器

本文介绍了REST架构的基本概念及其重要性,详细解析了HTTP动词如何映射到RESTful API的操作。此外,还深入探讨了Spring框架中的HiddenHttpMethodFilter过滤器,解释了它是如何实现将POST请求转化为PUT或DELETE请求的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、简单了解REST

REST(RepresentationalStateTransfer表述性状态转移),是目前最流行的一种互联网软件架构,它结构清晰,符合标准,易于理解,扩展方便。

  • 为啥REST如此重要?
  • 什么是REST架构 - z
  • 状态转换 (StateTransfer):HTTP协议是一个无状态的协议,所有的状态都保存在服务器端,如果客户端想操作服务器,必须通过某种手段,让服务器发生状态改变,而这种转变是建立在表现层之上的。
  • 在HTTP协议里面,有四个表示操作方式的动词 :GET、POST、PUT、DELETE。他们分别对应四种操作 :GET(获取资源)、POST(新建资源)、PUT(更新资源)、DELETE(删除资源)

      示例:/order/{id}
                /order/1         HTTP GET :  得到id=1的order
                /order/1         HTTP PUT :  更新id=1的order
                /order/1         HTTP DELETE:  删除id=1的order
                /order           HTTP POST:  新建order
    

    浏览器form表单只支持GET、POST 请求,而DELETE、PUT method属性并不支持。Spring3.0添加了一个过滤器 HiddenHttpMethodFilter,可以将POST 请求转为 PUT、DELETE 请求。

2、HiddenHttpMethodFilter

2.1 HiddenHttpMethodFilter的源码

public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method";

    public HiddenHttpMethodFilter() {
    }

    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

    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 HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
            filterChain.doFilter(wrapper, response);
        } else {
            filterChain.doFilter(request, response);
        }

    }

    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
        private final String method;

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
            super(request);
            this.method = method;
        }

        public String getMethod() {
            return this.method;
        }
    }
}

1):分析该过滤器的doFilterInternal方法

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

request.getMethod()会返回请求的方式(官方文档的注释:Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT. Same as the value of the CGI variable REQUEST_METHOD.)。可以看出 该过滤器只对POST请求进行转换,GET请求不做任何处理,转发给DispatcherServlet

2):

public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method";
    --------------
    String paramValue = request.getParameter(this.methodParam);
    -------------
    String method = paramValue.toUpperCase(Locale.ENGLISH);

根据这几条语句可以看出,请求中需包含一个 隐藏表单域(name默认值为_method,value值为PUT或DELETE,value值会转成大写)

3):在获取到 需要转换的 目标请求方式(String method = paramValue.toUpperCase(Locale.ENGLISH);)后,调用该过滤器的静态内部类HttpMethodRequestWrapper的HttpMethodRequestWrapper方法,将请求进行包装,并设置请求方式(method变量值),然后将转换后的请求转发给DispatcherServlet

3、启用HiddenHttpMethodFilter 过滤器

3.1 在web.xml中配置该过滤器

    <!-- 配置HiddenHttpMethodFilter -->
    <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>

3.2 表单示例

<form action="springmvc/test" method="post">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="submit"/>
  </form>

参考:
http://docs.oracle.com/javaee/6/api/
https://ke.qq.com/course/159860
http://blog.youkuaiyun.com/qq_35928356/article/category/6944043

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值