美文网首页
Spring RestTemplate处理gzip压缩问题

Spring RestTemplate处理gzip压缩问题

作者: Toconscience | 来源:发表于2018-09-09 22:00 被阅读506次

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

    相关文章

      网友评论

          本文标题:Spring RestTemplate处理gzip压缩问题

          本文链接:https://www.haomeiwen.com/subject/kkmdgftx.html