2017-02-03 2 views
2

私は圧縮なっている私の春ブーツアプリと、すべてのAPIの応答にコンテンツの圧縮を有効にしているが、私はRestTemplateを使用して、これらのAPIを打つ場合、私はSpringのAsyncRestTemplateではなく、JSONオブジェクトの内容を圧縮しはじめ、zip形式のコンテンツで作業していない

などのコンテンツを取得私は私の RestTemplateオブジェクトを作成し、私の交換要求にヘッダを設定しながら headers.set("Content-Encoding", "gzip"); headers.set("Accept-Encoding", "gzip");を追加するために HttpClientBuilder.create().build()を使用する場合、API自体は文字列を返すので
"\u001F�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000�}��8��¨OtD���1��]�m�mo��v�_LlP\u0014J�4E��(�����C�:\u0012<D\u0010����\b۲��\u0004\[email protected]\" 

はしかし、私は、文字列形式で適切なJSONオブジェクトを受け取ります。

AsyncRestTemplateを使用してこれらのAPIにアクセスしているときに私は同じ問題に直面しています。既にRestTemplateというオブジェクトを使用してAsyncRestTemplateオブジェクトを作成しても同じです。

自分自身でスレッドプールを実装してから、RestTemplateを使用してリクエストをヒットしますが、スレッド化メカニズムを実装していない圧縮コンテンツの代わりにjsonオブジェクトを取得する方法はありますか?以下は

は、私はむしろちょうど実際にウェブサーバによって行われます圧縮する(あなたのためにこれを行うに春を告げる、あなたは手動で圧縮をしないお勧めしたいと思い

public class RestUtil { 

    @Resource RestTemplate restTemplate; 
    @Resource AsyncRestTemplate asyncRestTemplate; 

    private final Log log = LogFactory.getLog(getClass()); 

    public String getSyncResponse(HttpServletRequest request) { 
     final String URL = "not including url"; 

     UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(URL); 

     HttpEntity<String> entity = new HttpEntity<>(null, getHeaders(request)); 
     try { 
      ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), GET, entity, String.class); 
      System.out.println("==== sync response ===="); 
      System.out.println(response.getBody()); 
      System.out.println("========"); 
      return response.getBody(); 
     } catch (Exception ex) { 
      log.error("Error in connecting to codebook server ", ex); 
     } 
     return null; 
    } 

    public List<String> getAsyncResponse(HttpServletRequest request) { 

     List<String> urls = new ArrayList<>(); 
     urls.add("not including url"); 
     urls.add("not including url"); 

     HttpEntity<String> entity = new HttpEntity<>(null, getHeaders(request)); 
     try { 

      ArrayList<Future<ResponseEntity<String>>> futures = new ArrayList<>(); 

      for (String url : urls) { 
       ListenableFuture<ResponseEntity<String>> listenableFuture = asyncRestTemplate.exchange(url, GET, entity, String.class); 
       listenableFuture.addCallback(response -> log.info("Success"), ex -> log.error("Request failed", ex)); 
       futures.add(listenableFuture); 
      } 

      List<String> responses = new ArrayList<>(); 
      for (Future<ResponseEntity<String>> future : futures) { 
       responses.add(future.get().getBody()); 
      } 

      System.out.println("==== async response ===="); 
      System.out.println(responses); 
      System.out.println("========"); 

      return responses; 

     } catch (Exception ex) { 
      log.error("Error in connecting to server ", ex); 
     } 
     return null; 
    } 

    private HttpHeaders getHeaders(HttpServletRequest request) { 
     HttpHeaders headers = new HttpHeaders(); 
     headers.set("Accept", APPLICATION_JSON_UTF8_VALUE); 
     headers.set("Content-Type", APPLICATION_JSON_UTF8_VALUE); 
     headers.set("Content-Encoding", "gzip"); 
     headers.set("Accept-Encoding", "gzip"); 
     Enumeration<String> headerNames = request.getHeaderNames(); 
     while (headerNames.hasMoreElements()) { 
      String header = headerNames.nextElement(); 
      Enumeration<String> headerList = request.getHeaders(header); 
      headers.put(header, Collections.list(headerList)); 
     } 

     return headers; 
    } 
} 


@Configuration 
class HttpConfig { 

    @Bean 
    public RestTemplate restTemplate() { 
     RestTemplate restTemplate = new RestTemplate(httpRequestFactory()); 

     MappingJackson2HttpMessageConverter jsonHttpMessageConverter = new MappingJackson2HttpMessageConverter(); 
     jsonHttpMessageConverter.getObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 
     restTemplate.getMessageConverters().add(jsonHttpMessageConverter); 

     return restTemplate; 
    } 

    @Bean 
    public ClientHttpRequestFactory httpRequestFactory() { 
     return new HttpComponentsClientHttpRequestFactory(httpClient()); 
    } 

    @Bean 
    public CloseableHttpClient httpClient() { 
     return HttpClientBuilder.create().build(); 
    } 

    @Bean 
    public AsyncRestTemplate asyncRestTemplate(AsyncClientHttpRequestFactory asyncHttpRequestFactory, RestTemplate restTemplate) { 
     return new AsyncRestTemplate(asyncHttpRequestFactory, restTemplate); 
    } 

    @Bean 
    public AsyncClientHttpRequestFactory asyncHttpRequestFactory() { 
     SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 
     requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor()); 
     return requestFactory; 
    } 

} 

答えて

1

完全なコードにある(Tomcatなど)しかし、Springはこれをあなたのために行います)。通常、圧迫のような春のようなもので、エンコーディングは、自動的に応答を解凍し、http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#how-to-enable-http-response-compression

+0

はい、春は私のためにそれをやっている私はちょうど=真 server.compression.mimeをserver.compression.enabled私のapplication.propertiesファイルにこれらのプロパティを書かれています-types = application/javascript、application/x-javascript、application/json、application/xml、text/html、text/xml、text/css、text/plain –

2

簡単な回避策がAsyncRestTemplateとResponseInterceptorを追加して見て下さいちょうど単一のプロパティ

によってオンにすることができます。受け取ったListenableFutureには、すでに圧縮解除された応答があります。ここで は例です:私は手動でそれをやっておりません

AsyncRestTemplate getAsyncRestTemplate() { 
    final HttpComponentsAsyncClientHttpRequestFactory httpComponentsAsyncClientHttpRequestFactory = 
      new HttpComponentsAsyncClientHttpRequestFactory(); 

    final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(httpComponentsAsyncClientHttpRequestFactory); 
    asyncRestTemplate.setInterceptors(Collections.singletonList((httpRequest, bytes, asyncClientHttpRequestExecution) -> { 
     if (!httpRequest.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) { 
      httpRequest.getHeaders().set(HttpHeaders.ACCEPT_ENCODING, "gzip"); 
     } 
     final ListenableFuture<ClientHttpResponse> future = asyncClientHttpRequestExecution.executeAsync(httpRequest, bytes); 
     return new ListenableFutureAdapter<ClientHttpResponse, ClientHttpResponse>(future) { 
      @Override 
      protected ClientHttpResponse adapt(ClientHttpResponse clientHttpResponse) throws ExecutionException { 
       return new InflatedClientHttpResponse(clientHttpResponse); 
      } 
     }; 
    })); 
    return asyncRestTemplate; 

} 

public class InflatedClientHttpResponse implements ClientHttpResponse { 
    private final ClientHttpResponse clientHttpResponse; 
    private final Boolean isCompressed; 

    public InflatedClientHttpResponse(ClientHttpResponse clientHttpResponse) { 
     this.clientHttpResponse = clientHttpResponse; 
     final HttpHeaders httpHeaders = clientHttpResponse.getHeaders(); 

     final List<String> contentEncoding = httpHeaders.get(HttpHeaders.CONTENT_ENCODING); 
     if (contentEncoding != null && contentEncoding.contains("gzip")) { 
      isCompressed = true; 
     } else { 
      isCompressed = false; 
     } 

     httpHeaders.remove(HttpHeaders.CONTENT_ENCODING); 
     httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); 
    } 

    @Override 
    public HttpStatus getStatusCode() throws IOException { 
     return clientHttpResponse.getStatusCode(); 
    } 

    @Override 
    public int getRawStatusCode() throws IOException { 
     return clientHttpResponse.getRawStatusCode(); 
    } 

    @Override 
    public String getStatusText() throws IOException { 
     return clientHttpResponse.getStatusText(); 
    } 

    @Override 
    public void close() { 
     clientHttpResponse.close(); 
    } 

    @Override 
    public InputStream getBody() throws IOException { 
     if (isCompressed) { 
      return new GZIPInputStream(clientHttpResponse.getBody()); 
     } 
     return clientHttpResponse.getBody(); 
    } 

    @Override 
    public HttpHeaders getHeaders() { 
     return clientHttpResponse.getHeaders(); 
    } 
} 
関連する問題