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

在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

时间: 2024-10-24 05:49:44

Tomcat + Spring MVC + HttpClient:怎样使用PUT和PATCH方法传递数据的相关文章

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

在RESTful风格的API中,PUT/PATCH方法一般用于更新数据.在项目的代码中,使用的是HttpClient 4.5,是这样写的: protected JSONObject doHttpUriRequest(HttpUriRequest httpUriRequest) { JSONObject result = null; HttpClient httpClient = HttpClients.createDefault(); try { HttpResponse httpRespons

Spring基础系列14 -- Spring MVC 请求参数的几种获取方法

Spring MVC 请求参数的几种获取方法 转载:http://www.cnblogs.com/leiOOlei/p/3658147.html 一.      通过@PathVariabl获取路径中的参数 @RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET) public String printMessage1(@PathVariable String id,@PathVariable String n

【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回

作者:ssslinppp      时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MVC与json参考文章:[spring学习笔记-mvc-3]返回json数据-方式1  和 [spring学习笔记-mvc-4]返回json数据-方式2. 使用到的技术主要如下: Ajax:使用JQuery 提供的ajax:==>需要引入jquery.min.js文件: Spring MVC: Jso

spring mvc 返回字符串或者是view的方法

public class JsonView { public static ModelAndView Render(Object model, HttpServletResponse response) { MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter(); MediaType jsonMimeType = MediaType.APPLICATION_JSON;

Spring MVC中处理静态资源的多种方法

处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了. 因为一个网站的显示肯定会依赖各种资源:脚本.图片等,那么问题来了,如何在页面中请求这些静态资源呢? 还记得Spring MVC中的DispatcherServlet吗?它是Spring MVC中的前置控制器,若配置的拦截路径为“/”,那么所有的请求都将被它拦截.对静态资源的访问也属于一个请求,那么也会被它拦截,然后进入它的匹配流 程,我们知道它是根据HandlerMapping的配置来匹配的.而对于静态资源来说,默认的Spr

(转)Spring MVC中处理静态资源的多种方法

处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了. 因为一个网站的显示肯定会依赖各种资源:脚本.图片等,那么问题来了,如何在页面中请求这些静态资源呢? 还记得Spring MVC中的DispatcherServlet吗?它是Spring MVC中的前置控制器,若配置的拦截路径为“/”,那么所有的请求都将被它拦截.对静态资源的访问也属于一个请求,那么也会被它拦截,然后进入它的匹配流 程,我们知道它是根据HandlerMapping的配置来匹配的.而对于静态资源来说,默认的Spr

spring mvc 使用@ResponseBody报错的解决方法

spring 3.0 mvc在从后台向前台返回时要转化成json串,但页面上报了 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers 异常信息 org.springframework.web.HttpMediaTypeNotA

spring mvc接收参数方式,json格式返回请求数据

1 使用方法形参使用变量接收提交的数据 2 在方法的形参中使用模型接收数据 3 如果在提交的表单中有多个数据模型,需要创建一个新的Bean,里面的属性是要接收的对象变量. 4 接收提交的日期字符串,转换成Date类型.需要使用@InitBinder来转换 5 批量删除数据,使用数组接收要删除的id,在页面中使用相同name属性 6 批量提交,如何接收数据?需要新建一个Bean,List或者LinkedList/ArrayList来接收. 7 在两个不同的action方法之间执行转发.在retur

Spring MVC 实现web Socket向前端实时推送数据

最近项目中用到了webSocket服务,由后台实时向所有的前端推送消息,前端暂时是不可以发消息给后端的,数据的来源是由具体的设备数据收集器收集起来,然后通过socket推送给后端,后端收到数据后,再将这些数据推送给前端. 听起来业务逻辑有点复杂.其实单独的实现socket或websocket都比较简单,但是二者之间的数据传输问题,困扰了我很久.也想过用redis做一个消息队列,将socket接收到的数据处理后丢进去,然后再用websocket从redis里取出数据,再推送给前端. 但是.问题来了