环境:
jdk: 8
spring-boot: 2.x
一、问题描述
- 在spring-boot 项目中使用RestTemplate和AsyncRestTemplate,RestTemplate发送请求时不会出现乱码,但是AsyncRestTemplate会出现乱码情况
二、问题分析
- 首先想到是加请求头
application/json;charset=utf-8
, RestTemplate没问题,AsyncRestTemplate依旧乱码。
HttpHeaders headers = new HttpHeaders();
// 等价 ContentType: application/json;charset=utf-8
headers.add(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
asyncRestTemplate.postForEntity(url, new HttpEntity<>(data,headers), ResponseModel.class);
- 断点查看 MessageConverters
- RestTemplate : 有两个
StringHttpMessageConverter
,分别对应UTF-8
和ISO-8859-1
编码
- AsyncRestTemplate : 只有一个
StringHttpMessageConverter
,对应ISO-8859-1
编码
综上所述,可以看到 AsyncRestTemplate 默认缺少 utf-8 的解析器 , 所以造成无法编码成utf-8
三、解决方式 (两种方式差不多)
- 增加一个 UTF-8 解析器 (第一种)
private AsyncRestTemplate asyncRestTemplate ;
@PostConstruct
public void init(){
asyncRestTemplate = new AsyncRestTemplate() ;
// 增加一个 utf-8 解析器
asyncRestTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
}
- 删除原有的 StringHttpMessageConverter , 然后重新添加 UTF-8 解析器 (第二种)
private AsyncRestTemplate asyncRestTemplate ;
@PostConstruct
public void init(){
asyncRestTemplate = new AsyncRestTemplate() ;
// 删除所有的 StringHttpMessageConverter
Iterator<HttpMessageConverter<?>> iterator = asyncRestTemplate.getMessageConverters().iterator();
while (iterator.hasNext()) {
final HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
}
// 添加 UTF-8 的解析器
asyncRestTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
}
注意 :增加解析器后,最好在 post
、put
、delete
请求增加contentType 头信息,类似如下
HttpHeaders headers = new HttpHeaders();
// 等价 ContentType: application/json;charset=utf-8
headers.add(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
asyncRestTemplate.postForEntity(url, new HttpEntity<>(data,headers), ResponseModel.class);