Tomcat + Spring MVC + HttpClient:如何使用PUT和PATCH方法传递数据

原创 2015年07月22日 11:14:37

在RESTful风格的API中,PUT/PATCH方法一般用于更新数据。在项目的代码中,使用的是HttpClient 4.5,是这样写的:

protected JSONObject doHttpUriRequest(HttpUriRequest httpUriRequest) {
    JSONObject result = null;

    HttpClient httpClient = HttpClients.createDefault();
    try {
        HttpResponse httpResponse = httpClient.execute(httpUriRequest);
        StatusLine responseStatusLine = httpResponse.getStatusLine();

        int statusCode = responseStatusLine.getStatusCode();
        if (statusCode == 200) {
            HttpEntity responseEntity = httpResponse.getEntity();

            String jsonString = EntityUtils.toString(responseEntity, CHARACTER_SET);
            result = new JSONObject(jsonString);

            EntityUtils.consume(responseEntity);
        } else {
            // error handling
        }
    } catch (IOException e) {
        e.printStackTrace();
        return onLocalError(e);
    }

    return result;
}

protected JSONObject doHttpPatch(String uri, Map<String, String> params) {
    JSONObject result = null;

    HttpPatch httpPatch = new HttpPatch(uri);
    List<NameValuePair> nvps = constructNvps(params); // constructing name-value pair

    try {
        httpPatch.setEntity(new UrlEncodedFormEntity(nvps, CHARACTER_SET));
        result = doHttpUriRequest(httpPatch);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return onLocalError(e);
    }

    return result;
}

其中doHttpUriRequest()是一个处理发送请求的工具函数,doHttpPatch()是具体处理数据的函数。
可见写法和一个普通的POST请求差不多,只是将HttpPost换成HttpPatch。
可是在server端,比如在params中有一个参数叫key,值是value,在Controller里面,能识别到这是一个PATCH方法,可是key的值是null。就是Servlet不能从form里面获取参数。
Google查了一下原因,大体是说PATCH这个方法很新,就算到Tomcat 7.0.39也都不支持。那怎么破呢?有两个办法:

1. 用URI来请求

既然不能使用form来获取参数,那就写在URI的尾巴吧:

protected JSONObject doHttpPatchWithURI(String uri, Map<String, String> params) {
    JSONObject result = null;
    URIBuilder uriBuilder = new URIBuilder();
    uriBuilder.setPath(uri);
    uriBuilder.setParameters(constructNvps(params));

    try {
        URI builtUri = uriBuilder.build();
        HttpPatch httpPatch = new HttpPatch(builtUri);
        result = doHttpUriRequest(httpPatch);
    } catch (URISyntaxException e) {
        e.printStackTrace();
        return onLocalError(e);
    }

    return result;
}

使用了这种做法,servlet可以获得参数了。
这个方法有一个问题。就是即使key是null值,在URI的参数也会带上。在Servlet里面接收,key的值会变成”“(空字符串)。这样在RESTful风格API里面会有歧义:究竟是不更新,还是更新成空字符串呢?

2. 在web.xml中加入一个filter

另一种做法是保持使用上面POST风格的方法,在web.xml中加入一个filter:

<filter>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <servlet-name>springWebMvcDispatcher</servlet-name>
</filter-mapping>

其中springWebMvcDispatcher是servlet的名字。
Filter的工作是从request body的form data里面读取数据,然后包装成一个ServletRequest,使得ServletRequest.getParameter*()之类的方法可以读取到数据。

参考文档:
http://stackoverflow.com/questions/20370927/patch-method-in-tomcat-with-spring-mvc

Java后台框架篇--Spring与Restful风格API接口开发

Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机...
  • hello_worldee
  • hello_worldee
  • 2017-09-30 13:45:21
  • 2283

spring MVC 管理HttpClient---实现在java中直接向Controller发送请求

在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在java代码中直接向controller发送请求,这时可以使用HttpCilent实...
  • u012116457
  • u012116457
  • 2015-06-19 22:59:46
  • 23800

http请求使用patch,后台Springmvc处理请求参数问题

SpringMVC后台获取http的patch类型请求的参数。
  • u011548068
  • u011548068
  • 2017-02-28 13:04:01
  • 4151

Android/Java 中利用HttpClient 发送Patch请求,携带Json参数

由于项目的需要,在前面记录过利用HttpUrlConnection发送Put请求的方法,链接在这http://blog.csdn.net/crystaldestiny/article/details/...
  • CrystalDestiny
  • CrystalDestiny
  • 2015-06-15 17:13:43
  • 4022

利用HttpClient 发送Patch请求,携带Json参数

HttpClient 中没有HttpPatch类,可以继承HttpPut来实现 import org.apache.http.client.methods.HttpPut; public clas...
  • gao1440156051
  • gao1440156051
  • 2017-01-16 16:40:21
  • 2100

SpringMVC浅谈

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。...
  • Gane_Cheng
  • Gane_Cheng
  • 2016-10-11 21:28:54
  • 5259

RESTFUL服务中POST/PUT/PATCH方法的区别

经常会混淆HTTP的POST/PUT方法,因为这两个方法似乎都可以用来创建或更新一个资源。区别是细微但清楚的:POST方法用来创建一个子资源,如 /api/users,会在users下面创建一个use...
  • iefreer
  • iefreer
  • 2013-08-27 19:41:24
  • 43202

Angular HttpClient http请求示例(GET、PUT、 PATCH、POST、DELETE)

Getting Started With Angular 4.3+ HttpClient 将已有的项目添加到github 创建RESTAPI神器-JsonServer Angular-cli新...
  • wanglui1990
  • wanglui1990
  • 2018-01-26 17:36:05
  • 817

轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)

版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载请声明:【转自 http://blog.csdn.net/xiaoxian8023 】 搜了一下网络上别人封装的HttpCli...
  • z90818
  • z90818
  • 2016-08-22 14:09:28
  • 2914

PATCH Method of HTTP

PATCH Method for HTTP draft-dusseault-http-patch-11 Status of this Memo By submitting this ...
  • afandaafandaafanda
  • afandaafandaafanda
  • 2015-04-10 16:27:37
  • 992
收藏助手
不良信息举报
您举报文章:Tomcat + Spring MVC + HttpClient:如何使用PUT和PATCH方法传递数据
举报原因:
原因补充:

(最多只允许输入30个字)