【发布时间】:2016-06-09 09:50:29
【问题描述】:
我有一个基于 Spring 3.2.0 构建的 Java 应用程序,它执行对提供 JSON 数据的 REST api 的外部调用。
调用由 Spring RestTemplate 类执行,Jackson 2.2.3 作为序列化器/反序列化器。
调用是函数式的,支持普通响应和压缩响应。
为了测试 Junit 调用,我使用 MockRestServiceServer。一切正常,直到我尝试引入 gzip 压缩。我无法在官方文档中找到如何在 MockRestServiceServer 中激活 gzip 压缩,所以我选择了手动路线:
手动压缩响应的字符串内容
在标头中将“Content-Encoding”设置为“gzip”
不幸的是,杰克逊在反序列化响应正文时一次又一次地收到相同的错误:
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
这是当前代码(由于公司数据而重做...)
测试类
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 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; } }
我觉得我错过了什么。手动 gzip 压缩似乎相当可疑。
有人对此有想法吗?
提前感谢您的回答!
【问题讨论】:
标签: java junit compression gzip resttemplate