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

本文介绍Spring框架中RestTemplate的DELETE方法不支持请求体的原因及其解决方案。通过修改RequestFactory并自定义支持请求体的DELETE请求模型,可以实现在DELETE请求中发送请求体。

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

        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;
}

### 使用WebClient发送请求体DELETE请求 在Spring框架中,默认情况下HTTP/1.1协议规定`DELETE`方法不应该包含消息主体。然而,在某些特定场景下,服务器端可能期望接收有一个实体的消息来执行删除操作。对于这种情况,可以尝试通过设置自定义的`HttpMessageWriter`或者利用一些变通的方法实现这一目标。 当使用`WebClient`构建器模式创建客户端实例时,可以通过`.method(HttpMethod.DELETE)`指定请求方式并调用`.body()`函数传递请求体数据[^1]: ```java import org.springframework.http.HttpMethod; import reactor.core.publisher.Mono; // 创建WebClient对象 WebClient client = WebClient.builder().baseUrl("http://example.com").build(); Mono<Void> response = client.method(HttpMethod.DELETE) .uri("/resource/{id}", id) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(requestBody), RequestBodyClass.class) .retrieve() .toBodilessEntity(); // 如果响应不包含内容,则转换为空值 ``` 需要注意的是,并不是所有的服务器都能正确处理附正文的`DELETE`请求;因此建议先确认API文档中的具体需求再做相应调整。另外,如果遇到问题也可以考虑改用其他类型的HTTP动词如POST模拟删除行为[^2]。 #### 关于编码配置 为了确保能够顺利解析以及序列化JSON或其他格式的数据作为请求体的一部分,应该检查项目依赖项里是否有合适的库存在(比如Jackson用于JSON支持),因为这些会被CodecConfigurer自动检测到并应用合理的默认设置[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值