• 通过 Spring RestTemplate 调用带请求体的 Delete 方法(Delete With Request Body)


            Spring 框架的RestTemplate 类定义了一些我们在通过 java 代码调用 Rest 服务时经常需要用到的方法,使得我们通过 java 调用 rest 服务时更加方便、简单。但是 RestTemplate 的 delete 方法并不支持传入请求体(Request Body)。经测试,通过调用 RestTemplate 类的exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<ResponseResult> responseType, Object... uriVariables)  方法,将 method 指定为 org.springframework.http.HttpMethod.DELETE,并传入 requestEntity(请求体) 对象时,在服务端得到的 Request Body 仍然为 null。可见 RestTemplate 默认并不支持对 DELETE 方法使用请求体。

            通过查阅资料发现 RestTemplate 默认是使用 spring 自身的 SimpleClientHttpRequestFactory 创建请求对象和对其进行相关设置(如请求头、请求体等),它只支持 PUT 和 POST 方法带请求体,RestTemplate 的 DELETE 方法不支持传入请求体是因为 JDK 中 HttpURLConnection 对象的 delete 方法不支持传入请求体(如果对 HttpURLConnection 对象的 delete 方法传入请求体,在运行时会抛出 IOException)。

            我们可以通过修改 RestTemplate 的 RequestFactory 实现 delete 方法对请求体的支持,比如改成 Apache HTTPClient’s HttpComponents 的ClientHttpRequestFactory,由于 ClientHttpRequestFactory 默认的 DELETE 方法也不支持请求体,所以我们除了修改 RestTemplate 的 RequestFactory 之外,还需要定义一个支持传输请求的的 DELETE 请求模型,完整的代码如下:

    RestTemplate restTemplate = new RestTemplate();
     
    public static class HttpEntityEnclosingDeleteRequest extends HttpEntityEnclosingRequestBase {
     
        public HttpEntityEnclosingDeleteRequest(final URI uri) {
            super();
            setURI(uri);
        }
     
        @Override
        public String getMethod() {
            return "DELETE";
        }
    }
     
    @Test
    public void bodyWithDeleteRequest() throws Exception {
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory() {
            @Override
            protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
                if (HttpMethod.DELETE == httpMethod) {
                    return new HttpEntityEnclosingDeleteRequest(uri);
                }
                return super.createHttpUriRequest(httpMethod, uri);
            }
        });
     
        ResponseEntity<String> exchange = restTemplate.exchange(
                "http://example.com/file";,
                HttpMethod.DELETE,
                new HttpEntity<String>("some sample body sent along the DELETE request"),
                String.class);
        assertEquals("Got body: some sample body sent along the DELETE request", exchange.getBody());
    }

    服务端的 java 代码:

    @RequestMapping(value = "/file", method = DELETE)
    @ResponseBody
    public String deleteSecci(@RequestBody String body) {
        return "Got body: " + body;
    }

  • 相关阅读:
    bzoj3033
    noip2016 Day1T3
    编译php的问题
    JavaScript <script>标签的位置、延迟脚本(defer属性)与 异步脚本(async属性)
    连接远程数据库时出现 SSH: expected key exchange group packet from server / 2003
    laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy
    laravel 生成 key
    windows下apache配置虚拟主机
    composer设置忽略版本匹配
    laravel 服务容器实例——深入理解IoC模式
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3151391.html
Copyright © 2020-2023  润新知