問題描述
工作中交接了一個項目,發現了一個奇特的bug。
調用某個渠道獲得響應,是亂碼顯示,首先排查其他渠道方,響應均爲正常。聯繫後對方表示使用Postman調用響應正常,只能從我們這邊入手查詢。
使用curl -v調用渠道方接口也發現,響應的報文是正確,並未出現亂碼現象。
仔細排查後發現!響應頭裏Content-Type中,application/json;charset=utf-8當中多了一個空格,正是這個空格的原因導致了RestTemplate無法解析響應,出現了亂碼。但是渠道方近期無版本,不能配合改造,那隻能從我們這邊入手了。
RestTemplate源碼解析
注意下面圖裏的兩行代碼
從響應中獲取了contentType,轉成MediaType,但在org.springframework.http.MediaType類中,是不包含帶有空格格式的contentType
public static final String APPLICATION_JSON_VALUE = "application/json";
public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
所以消息轉換器的canRead方法,無法正確的解析,找到問題所在,那我們只需要讓消息轉換器能識別這種類型即可。
解決方法
@Autowired
RestTemplateBuilder builder;
private RestTemplate getRestTemplate() {
List<HttpMessageConverter<?>> converters = builder.build().getMessageConverters();
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
try {
List<MediaType> mediaTypeList = new ArrayList<>(converter.getSupportedMediaTypes());
// 增加MediaType
mediaTypeList.add(new MediaType("application/json; charset=utf-8"));
((MappingJackson2HttpMessageConverter) converter).setSupportedMediaTypes(mediaTypeList);
} catch (Exception e) {
e.printStackTrace();
}
}
}
RestTemplate restTemplate = builder.build();
return restTemplate;
}
一個小小的空格引發的問題,浪費了許多時間去排查,寫代碼還是要規範,避免這種問題。