记录中国天气网接口返回乱码问题解决方法
简介: Spring RestTemplate 调用天气预报接口可能遇到中文乱码的问题,解决思路如下。
Spring RestTemplate 调用天气预报接口可能遇到中文乱码的问题,解决思路如下。
问题出现
我们在网上找了一个免费的天气预报接口 http://wthrcdn.etouch.cn/weather_mini?citykey=101280601。我们希望调用该接口,并将返回的数据解析为 JSON 格式。
核心业务逻辑如下:
private WeatherResponse doGetWeatherData(String uri) {
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
String strBody = null;
if (response.getStatusCodeValue() == 200) {
strBody = response.getBody();
}
ObjectMapper mapper = new ObjectMapper();
WeatherResponse weather = null;
try {
weather = mapper.readValue(strBody, WeatherResponse.class);
} catch (IOException e) {
e.printStackTrace();
}
return weather;
}
在浏览器里面访问该接口都挺正常。如下图所示:
但在纯 Spring 应用里面,尝试使用 RestTemplate 来调用,结果解析数据为 JSON 失败,因为数据有乱码。如下图所示:
尝试进行编码转换
一开始,我们认为这可能是对方转过来的数据不是 UTF-8 导致的,所以,尝试加入了消息转换器。
@Configuration
public class RestConfiguration {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1,
new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 支持中文编码
return restTemplate;
}
}
StringHttpMessageConverter 默认是 ISO_8859_1,所以我们设置为了 UTF_8。
再次执行,发现仍然是乱码。
找到问题的根源
这一次我没有再瞎猜了,而是仔细观察了 HTTP 的请求协议。发现消息头里面的蛛丝马迹:
原来,数据是经过 GZIP 压缩过的。默认情况下, RestTemplate 使用的是 JDK 的 HTTP 调用器,并不支持 GZIP 解压,难怪解析不了。
解决方案
既然找到了问题所在,解决起来就简单了。主要考虑了以下方案。
尝试删除此header 的 accept 的 gzip
测试一切正常,完美解决!