简体   繁体   English

使用MockRestServiceServer进行Gzip压缩

[英]Gzip compression with MockRestServiceServer

I have a Java application built on Spring 3.2.0 performing an external call to a REST api serving JSON data. 我有一个基于Spring 3.2.0构建的Java应用程序, 它对提供JSON数据的REST API进行了外部调用。

The call is performed by the Spring RestTemplate class, with Jackson 2.2.3 as serializer/deserializer. 调用由Spring RestTemplate类执行,将Jackson 2.2.3作为序列化器/解串器。

The call is functionnal and supports both plain and gzipped responses. 该调用是功能性的,并且支持简单响应和压缩响应。

In order to Junit test the call, I use MockRestServiceServer . 为了测试Junit呼叫,我使用MockRestServiceServer Everything works well, until I try to introduce gzip compression. 一切正常,直到我尝试引入gzip压缩。 I was unable to find in the offical doc how to activate gzip compression in MockRestServiceServer, so I went the manual route : 我无法在官方文档中找到如何在MockRestServiceServer中激活gzip压缩,所以我走了一条手工路线:

  • manually gzip the String content of the response 手动gzip响应的字符串内容

  • set the "Content-Encoding" to "gzip" in the headers 在标题中将“ Content-Encoding”设置为“ gzip”

Unfortunately, I get the same error again and again, thrown by Jackson when deserializing the response body : 不幸的是,我一次又一次遇到相同的错误,由杰克逊在反序列化响应正文时抛出:

 org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\\r, \\n, \\t) is allowed between tokens at [Source: java.io.ByteArrayInputStream@110d68a; line: 1, column: 2]; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\\r, \\n, \\t) is allowed between tokens 

Here is the current code (reworked due to corporate data...) 这是当前代码(由于公司数据而被重做...)

Test class 测试班

 public class ImportRefCliCSTest { @Autowired private MyService myService; private MockRestServiceServer mockServer; @Before public void before() { mockServer = MockRestServiceServer.createServer(myService.getRestTemplate()); } @Test public void testExternalCall() throws IOException { String jsonData = "[{\\"testing\\":\\"Hurray!\\"}]"; HttpHeaders headers = new HttpHeaders(); headers.add( "Content-Encoding", "gzip" ); DefaultResponseCreator drc = withSuccess( gzip( jsonData ), MediaType.APPLICATION_JSON ).headers( headers ); mockServer.expect( requestTo( myService.EXTERNAL_CALL_URL ) ) .andExpect( method( HttpMethod.GET ) ).andRespond(drc); myService.performCall(); } private static String gzip(String str) throws IOException { if (str == null || str.length() == 0) { return str; } ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(out); gzip.write(str.getBytes()); gzip.close(); String outStr = out.toString(); return outStr; } } 

Service class 服务等级

 @Service public class MyService { public static final String EXTERNAL_CALL_URL = "<myURL>"; private RestTemplate restTemplate; { restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory( HttpClientBuilder.create().build())); } public void performCall() { try { HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Accept-Encoding", "gzip"); HttpEntity<MyObject[]> requestEntity = new HttpEntity<MyObject[]>(requestHeaders); ResponseEntity<MyObject[]> responseEntity = restTemplate.exchange( EXTERNAL_CALL_URL, HttpMethod.GET, requestEntity, MyObject[].class); MyObject[] array = responseEntity.getBody(); if (array == null || array.length == 0) { return null; } return null; } catch (RestClientException e) { return null; } } public RestTemplate getRestTemplate(){ return restTemplate; } } 

I feel I am missing something. 我觉得我缺少什么。 The manual gzip compression seems rather suspicious. 手动gzip压缩似乎相当可疑。

Does anyone have an idea on this ? 有人对此有想法吗?

Thanks in advance for your answers ! 预先感谢您的回答!

When program convert gzip content to string, some bytes are collapsed. 当程序将gzip内容转换为字符串时,某些字节将被折叠。 So client cannot decompress it and throw Exception. 因此客户端无法解压缩它并引发Exception。 A solution is return byte[] : 一个解决方案是返回byte[]

private static byte[] gzip(String str) throws IOException {
    if (str == null || str.length() == 0) {
        return new byte[0];
    }
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(out);
    gzip.write(str.getBytes());//consider to use str.getBytes("UTF-8")
    gzip.close();
    return out.toByteArray();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM