Spring RestTemplate处理gzip压缩问题

2018-09-09  本文已影响506人  Toconscience

最近使用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.

上一篇下一篇

猜你喜欢

热点阅读