美文网首页程序员
PATCH METHOD使用

PATCH METHOD使用

作者: 老夫乃野马只待皮鞭抽 | 来源:发表于2017-07-03 22:34 被阅读0次

    背景

    目前广泛使用的HTTP/1.1中定义了八个基本动作①,而PATCH属于扩展动作出现较晚②,很多容器或者库类的API都没有支持。所以我们在处理PATCH方法时常常需要使用一些额外的方法。

    语义

    用于更新资源的部分内容。例如,更新用户信息中的姓名字段。

    和PUT对比

    1. 当资源存在时:
      • PATCH 用于资源的部分内容的更新
      • PUT 用于更新某个资源较完整的内容
    2. 当资源不存在时
      • PATCH 可能会去创建一个新的资源,像是 saveOrUpdate
      • PUT 只对已有资源进行更新操作,所以是 update 操作

    实现和支持

    • 支持:

      • Apache HttpComponents HttpClient version 4.2 or later 支持了 PATCH
      • Spring 3.2 开始支持 PATCH 方法,但要选对部署的容器
      • JBoss Netty 支持 PATCH
    • 不支持:

      • 目前 JDK7 的 HttpURLConnection 未实现 PATCH
      • TOMCAT 7 也不行
      • PlayFramework 2 也不支持

    在Spring中使用PATCH

    背景

    PATCH方法默认是以x-www-form-urlencoded③的contentType来发送信息,并且信息内容是放在request的body里。而
    Springmvc在解析参数的时候使用的解析器是ServletModelAttributeMethodProcessor,该解析器不支持PATCH,当使用getParameterMap()获取body内容的时候,获取不到信息。

    解决办法

    1.使用查询字符串传参:

    使用POSTMAN模拟客户端发起请求:


    查询字符串传参

    服务端接收参数:

     /**
      * 更新 (客户端上送部分数据)
      * patch 传递参数的方法:
      *  1) 使用查询字符串
      */
     @RequestMapping(path = "{id}", method = RequestMethod.PATCH)
     @ResponseBody
     public String patch(@PathVariable String id, UserInfo userInfo) {}
    
    2.使用@RequestBody + JSON :

    Spring中使用@RequestBody来绑定数据时,使用的是RequestResponseBodyMethodProcessor来解析参数,该解析器可以将json格式的内容装载到pojo里。而@RequestBody只支持以下几种contentType:application/jsonapplication/hal+jsonapplication/pathc+jsonapplication/merge-pathc+json。示例如下:

    1)使用PostMan测试

    使用POSTMAN模拟客户端发起请求:

    • 设置contentType为application/json
    设置contentType
    • 在body中使用JSON传参
    JSON数据

    服务端接收请求:

    /**
     * 更新 (客户端上送部分数据)
     * patch 传递参数的方法:
     *  1) @RequestBody + JSON
     */
    @RequestMapping(path = "{id}", method = RequestMethod.PATCH)
    @ResponseBody
    public String patch(@PathVariable String id, @RequestBody UserInfo userInfo) {}
    
    2)使用ajax作为客户端的代码
    $.ajax({
        url: 'http://localhost/v1/users/1',
        type: 'PATCH',
        contextType: 'application/json',
        data: JSON.stringify({
            name: '张三',
            age: '18'
        })
    })
    
    3. 使用表单隐藏字段(_method) + HiddenHttpMethodFilter

    使用POSTMAN模拟客户端发起请求:

    隐藏字段:_method

    服务端代码:

    • web.xml中增加filter
    <!-- 隐藏方法拦截器 -->
    <filter>
        <filter-name>HttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    • controller代码
     /**
      * 更新 (客户端上送部分数据)
      * patch 传递参数的方法:
      *  1) HiddenHttpMethodFilter + 额外字段_method
      */
     @RequestMapping(path = "{id}", method = RequestMethod.PATCH)
     @ResponseBody
     public String patch(@PathVariable String id, UserInfo userInfo) {}
    
    4. 使用HttpPutFormContenrFilter

    使用POSTMAN模拟客户端发起请求:

    没有_method字段

    服务端代码:

    • web.xml中增加filter
        <filter>
            <filter-name>HttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    • controller代码
     /**
      * 更新 (客户端上送部分数据)
      * patch 传递参数的方法:
      *  1) HttpPutFormContentFilter
      */
     @RequestMapping(path = "{id}", method = RequestMethod.PATCH)
     @ResponseBody
     public String patch(@PathVariable String id, UserInfo userInfo) {}
    

    注:

    • ①: 八个动作分别为: OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE、CONNECT
    • ②: 2010年3月份才成为正式方法,见“RFC 5789
    • ③:就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=Java&age = 23
    • ④: HiddenHttpMethodFilter和HttpPutFormContenrFilter的区别:

    HttpPutFormContenrFilter只能处理PUT和PATCH动作。其内部实现是获取以上两种请求的表单参数后,封装一个新的request包装类:

    HiddenHttpMethodFilter

    HiddenHttpMethodFilter除了PUT和PATCH还能处理DELETE等动作。但是必须增加一个隐藏参数_method,增加了客户端代码的耦合:

    HiddenHttpMethodFilter

    相关文章

      网友评论

        本文标题:PATCH METHOD使用

        本文链接:https://www.haomeiwen.com/subject/wbozcxtx.html