【问题标题】:Read JSON with HttpClient, REST and gzip使用 HttpClient、REST 和 gzip 读取 JSON
【发布时间】:2021-08-14 12:10:52
【问题描述】:

我正在尝试使用 HttpClient、POST 方法调用休息服务。 该服务使用 gzip 压缩返回一个 json。 由于某种原因,响应的 json 与日志中始终为空的字符串变量“输出”无关。 See image 在调试中我只能看到 json 的初始值。 entity.getContent() 的结果是 org.apache.http.conn.EofSensorInputStream@30f5a68a。 通过 SoapUI 进行的相同测试似乎没问题。

Java 代码

HttpPost httpPost = new HttpPost(endpoint);
httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader(HttpHeaders.ACCEPT_ENCODING, "gzip");
httpPost.addHeader(HttpHeaders.ACCEPT, "application/json");         
httpPost.setEntity(new StringEntity(jsonRequest));
        
        try (CloseableHttpClient httpClient = HttpClientBuilder.create().disableRedirectHandling().build();
                CloseableHttpResponse res = httpClient.execute(httpPost)) {

            HttpEntity entity = res.getEntity();
            LOG.debug(entity.getContent());
                
            if (entity != null) {

                String output = EntityUtils.toString(entity, "UTF-8");
                LOG.debug(output); // <------- empty LOG
            }

        } catch (Exception exc) {
            LOG.error(exc);
        }

Maven

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>

SAOP 用户界面请求

POST https://host HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json
Content-Length: 2627
Host: host
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

SAOP 用户界面响应

HTTP/1.1 200 OK
Date: Wed, 26 May 2021 08:48:57 GMT
Server: Apache
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
Cache-Control: no-store, no-cache
Pragma: no-cache
X-Backside-Transport: OK OK
Content-Type: application/json
X-Global-Transaction-ID: dc640eac60ae0b794b55bcaf
APIHttpStatus: 200
Content-Encoding: gzip
Keep-Alive: timeout=65
Connection: Keep-Alive
Transfer-Encoding: chunked

{"ShipmentResponse":{"Response":{"ResponseStatus":{"Code":"1", "Description":"Success"}, "Alert":[{"Code":"120900", "Description":"User Id ...

Soap UI Json view

【问题讨论】:

  • 通知传输编码:分块

标签: java rest gzip


【解决方案1】:

使用来自entity.getContent()的字符串

    GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(entity.getContent()));
    BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
    String outStr = "";
    String line;
    while ((line=bf.readLine())!=null) {
      outStr += line;
    }
    System.out.println("Output String lenght : " + outStr.length());

编辑:

似乎有一个 gzip 压缩内容的实体包装器: https://javadoc.io/doc/org.apache.httpcomponents/httpclient/latest/org/apache/http/client/entity/GzipDecompressingEntity.html

(new GzipDecompressingEntity(entity)).getContent()

【讨论】:

  • 使用 GZIPInputStream gis = new GZIPInputStream(entity.getContent());我得到:java.util.zip.ZipException:不是 GZIP 格式getContent 返回一个 InputStream
  • 另外,使用此代码,我得到一个完整的 EMPTY 日志行: [code] Reader decoder = new InputStreamReader(entity.getContent(), "UTF-8"); BufferedReader buffered = new BufferedReader(decoder); final String line = buffered.readLine(); LOG.debug(行); [代码]
  • 并且您可以看到它正在返回一些 json 的服务日志?
  • Transfer-Encoding: chunked后,Server返回一个压缩流:“[0x1f][0x8b][0x8][0x0][0x0][0x0][0x0][0x0][0x0][ 0x3][0xac][0xb9][0xd7][0xce](等等)。这是json字符串
  • 不错!您如何尝试使用 javadoc.io/doc/org.apache.httpcomponents/httpclient/latest/org/… ==> (new GzipDecompressingEntity(entity)).getContent()
猜你喜欢
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多