使用RestOperations exchange方法请求返回Http 406错误排查
问题原因
406 Not Acceptable错误的核心是服务器无法返回客户端请求的响应格式:
- 当你用
TokenResponse.class作为响应类型时,Spring的RestOperations实现(比如RestTemplate)会自动在请求头中添加Accept: application/json,要求服务器返回JSON格式。 - 但你的服务器可能不支持返回
application/json类型的响应,或者服务器实际返回的Content-Type和这个Accept头不匹配(比如服务器返回的是text/plain格式的JSON字符串)。 - 而改用
String.class时,Spring会设置宽松的Accept: */*头,服务器可以返回它支持的任意格式,因此能正常返回200和响应体。
解决方案
针对这个问题,有几种可行的解决方式:
1. 手动设置匹配的Accept请求头
先确认服务器实际支持返回的Content-Type(可以通过用String.class获取响应后,查看响应头的Content-Type值),然后在请求头中设置对应的Accept类型。比如如果服务器返回的是text/plain:
headers.setAccept(Collections.singletonList(MediaType.TEXT_PLAIN)); ResponseEntity<TokenResponse> response = restOperations.exchange( uri, HttpMethod.POST, new HttpEntity<>(body, headers), TokenResponse.class );
2. 配置消息转换器支持更多媒体类型
如果服务器返回的是JSON格式,但Content-Type不是标准的application/json(比如text/plain),可以扩展Spring的消息转换器,让它能处理这类非标准的JSON响应:
// 配置MappingJackson2HttpMessageConverter支持更多媒体类型 MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(); jacksonConverter.setSupportedMediaTypes(Arrays.asList( MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.APPLICATION_OCTET_STREAM )); // 将自定义转换器加入RestTemplate的转换器列表(放在最前面优先使用) RestTemplate restTemplate = (RestTemplate) restOperations; restTemplate.getMessageConverters().add(0, jacksonConverter);
3. 先获取字符串再手动反序列化
这种方式更直接,先拿到字符串响应,再用Jackson手动转成TokenResponse对象:
ResponseEntity<String> stringResponse = restOperations.exchange( uri, HttpMethod.POST, new HttpEntity<>(body, headers), String.class ); // 手动反序列化 ObjectMapper objectMapper = new ObjectMapper(); TokenResponse tokenResponse = objectMapper.readValue(stringResponse.getBody(), TokenResponse.class);
内容的提问来源于stack exchange,提问作者SRI HARSHA S V S
相关产品推荐
相关产品推荐

