You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot 3.2.0自定义RestTemplate未发送Content-Length问题

SpringBoot 3.2.0升级后Apache HttpClient RestTemplate缺失Content-Length导致411错误的解决方案

问题场景

将SpringBoot从3.1.5升级到3.2.0后,基于Apache HttpClient 5.2.3构建的自定义忽略SSL证书验证的RestTemplate,在发起POST请求时未自动设置Content-Length头部,导致被调用服务器返回411 Length Required错误。而在3.1.5版本(使用相同版本的HttpClient)中,该头部会被正常设置。

临时可通过以下方式规避:

  • POST请求无请求体时,发送空字符串""替代null
  • 手动将请求对象序列化为字符串后再发送

原因分析

SpringBoot 3.2.0对RestTemplate的请求处理逻辑做了调整:当请求体为null时,框架不再自动为POST请求添加Content-Length头部;而3.1.5版本中,即使请求体为空,也会默认设置Content-Length为0。这种变化导致依赖该头部的服务器返回411错误——HttpClient本身在处理空请求体时不会主动添加该头部,需要Spring的适配层来处理。

解决方案

方案1:统一替换空请求体为字符串""

在所有无请求体的POST请求中,将请求体参数设为空字符串"",这样HttpMessageConverter会正常序列化并计算内容长度,自动添加Content-Length: 0头部。

示例代码:

// 原写法(会触发问题)
restTemplate.postForObject("https://target-api.com/endpoint", null, String.class);

// 修改后
restTemplate.postForObject("https://target-api.com/endpoint", "", String.class);

方案2:添加请求拦截器强制设置Content-Length

通过自定义ClientHttpRequestInterceptor,对POST且无请求体的请求手动添加Content-Length头部。

1. 实现拦截器

import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

public class ContentLengthFixInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        // 针对POST请求,且请求体为空的情况,强制设置Content-Length为0
        if (HttpMethod.POST.equals(request.getMethod()) && (body == null || body.length == 0)) {
            request.getHeaders().setContentLength(0);
        }
        return execution.execute(request, body);
    }
}

2. 将拦截器添加到RestTemplate

在构建自定义RestTemplate的代码中,添加该拦截器:

RestTemplate restTemplate = new RestTemplate(getHttpClientRequestFactory());
// 添加拦截器
restTemplate.getInterceptors().add(new ContentLengthFixInterceptor());

方案3:自定义HttpMessageConverter处理空请求体

扩展MappingJackson2HttpMessageConverter(或你使用的其他转换器),当请求体为null时,返回空字节数组,并自动触发Content-Length计算。

示例代码:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class NullBodyJacksonConverter extends MappingJackson2HttpMessageConverter {
    public NullBodyJacksonConverter(ObjectMapper objectMapper) {
        super(objectMapper);
    }

    @Override
    protected byte[] getContent(Object object, MediaType contentType) throws IOException {
        if (object == null) {
            return "".getBytes(StandardCharsets.UTF_8);
        }
        return super.getContent(object, contentType);
    }
}

然后替换RestTemplate中的默认转换器:

ObjectMapper objectMapper = new ObjectMapper();
NullBodyJacksonConverter converter = new NullBodyJacksonConverter(objectMapper);
restTemplate.getMessageConverters().removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);
restTemplate.getMessageConverters().add(converter);

方案4:调整目标服务器配置(可选)

如果有权限修改被调用服务器的配置,可以关闭对POST请求Content-Length头部的强制校验,允许无请求体的POST请求。但该方案依赖第三方服务,通常不推荐作为首选。


内容的提问来源于stack exchange,提问作者Hylton Peimer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:29:58