最近使用RestTemplate访问一个API,总是得到乱码。Debug几遍,确认传入的HttpMessageConverter
编码正确,还是不行。最后注意到这个API使用了gzip压缩。我们使用浏览器或者Postman调用时,客户端自动就解压缩了。而RestTemplate,我们需要自己想办法处理。
方法一:自己解压缩
就是得到一个字节数组,然后再转化成String
方式1:使用Java原生类
ResponseEntity<byte[]> response = restTemplate.getForEntity(uri, byte[].class);
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(response.getBody()));
BufferedReader reader = new BufferedReader(new InputStreamReader(gzip));
StringWriter writer = new StringWriter();
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
}
String responseString = writer.toString();
方式2:使用Apache Commons IO的辅助方法
ResponseEntity<byte[]> response = restTemplate.getForEntity(apiUrl, byte[].class);
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(response.getBody()));
// convert the stream to string
StringWriter writer = new StringWriter();
IOUtils.copy(gzip, writer, "UTF-8");
String responseString = writer.toString();
方式3:使用Apache Commons JCS Core 的辅助方法
ResponseEntity<byte[]> responseBytes = restTemplate.getForEntity(apiUrl, byte[].class);
String decompressed = new String(CompressionUtil.decompressGzipByteArray(responseBytes), Charsets.UTF_8);
方法二:让Apache HttpClient帮我们解决
其实,RestTemplate的构造函数接受一个ClientHttpRequestFactory
,用来提供具体的http请求的实现。如果使用HttpComponentsClientHttpRequestFactory
这个实现类,则会在底层使用Apache HttpClient来做请求。而这种Http Client可以自动的帮我们处理压缩问题。
也就是说,我们的代码完全不用关心gzip压缩,一句话就搞定了:
responseString = restTemplate.getForObject(uri, String.class);
配置方式有两种。
方式一:显式配置
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
HttpClientBuilder.create().build());
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
方式二:使用builder隐式配置
首先要指定Apache Client依赖 (build.gradle)
compile('org.apache.httpcomponents:httpclient')
然后使用RestTemplateBuilder配置
@Configuration
public class RestConfiguration {
@Autowired
private RestTemplateBuilder builder;
@Bean
public RestTemplate restTemplate() {
return builder.build();
}
}
RestTemplateBuilder
会查看当前classpath,如果发现有Apache HttpClient,就使用HttpComponentsClientHttpRequestFactory
来创建RestTemplate.
网友评论