Spring Boot从2.7升级到3.1后RestTemplate调用报400错误
Spring Boot 2.7升级至3.1后RestTemplate发起HTTPS请求报400 Bad Request问题
问题描述
将Spring Boot从2.7版本升级到3.1版本后,使用RestTemplate调用内部HTTPS API时出现400 Bad Request错误,旧版本无此现象,确定由升级引发的框架变更导致。
错误信息
HTTP Error Message: <html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>400 Bad Request</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Bad Request</h1> <h2>Your client has issued a malformed or illegal request.</h2> <h2></h2> </body></html> ] with root cause org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: "<EOL><html><head><EOL><meta http-equiv="content-type" content="text/html;charset=utf-8"><EOL><title>400 Bad Request</title><EOL></head><EOL><body text=#000000 bgcolor=#ffffff><EOL><h1>Error: Bad Request</h1><EOL><h2>Your client has issued a malformed or illegal request.</h2><EOL><h2></h2><EOL></body></html><EOL>"
已参考相关Spring Boot官方问题但未找到有效解决方案。
可能的原因及解决方法
1. HTTP客户端默认实现变更
Spring Boot 3.x基于Spring Framework 6.x,RestTemplate默认使用的HTTP客户端实现可能发生了变化(比如从Apache HttpClient切换为JDK原生HttpClient),不同客户端对请求的处理逻辑存在差异,导致请求格式不符合内部API的要求。
解决办法:显式配置RestTemplate使用Apache HttpClient5,保持与旧版本一致的客户端实现:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { org.apache.hc.client5.http.classic.HttpClient httpClient = org.apache.hc.client5.http.classic.HttpClientBuilder.create() .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); } }
同时需要引入Apache HttpClient5依赖:
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> </dependency>
2. 请求编码或消息转换器配置变更
Spring Boot 3.x对请求编码、消息转换的处理更严格,且默认使用的Jackson版本(2.15+)存在序列化行为变更,可能导致请求体格式或编码不符合API要求。
解决办法:显式配置RestTemplate的消息转换器,指定UTF-8编码:
@Bean public RestTemplate restTemplate(ObjectMapper objectMapper) { RestTemplate restTemplate = new RestTemplate(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper); converter.setDefaultCharset(StandardCharsets.UTF_8); List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters(); converters.removeIf(c -> c instanceof MappingJackson2HttpMessageConverter); converters.add(converter); return restTemplate; }
3. SSL/TLS协议版本不兼容
Spring Boot 3.x默认启用的TLS协议版本可能高于内部API服务器支持的版本,导致SSL握手过程中请求被判定为非法。
解决办法:配置RestTemplate使用兼容的TLS版本(例如TLSv1.2):
@Bean public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(5000); factory.setReadTimeout(5000); return new RestTemplate(factory); }
4. 请求体格式或传递方式错误
升级后RestTemplate对空请求体、请求参数的处理逻辑发生变化,可能导致请求格式不符合内部API的校验规则。
解决办法:
- 检查请求调用方式,确保
postForObject/exchange等方法传递的请求体格式正确; - 若API不需要请求体,优先使用
getForObject等GET请求方法,或显式构造空请求体的合法格式。
内容的提问来源于stack exchange,提问作者Nani
相关产品推荐
相关产品推荐

