使用 HttpClient、REST 和 gzip 读取 JSON
Posted
技术标签:
【中文标题】使用 HttpClient、REST 和 gzip 读取 JSON【英文标题】:Read JSON with HttpClient, REST and gzip 【发布时间】: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
【问题讨论】:
通知传输编码:分块 【参考方案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()以上是关于使用 HttpClient、REST 和 gzip 读取 JSON的主要内容,如果未能解决你的问题,请参考以下文章
HttpClient AutomaticDecompression 与 gzip 一起使用,而不是放气
Apache Commons HttpClient 是不是支持 GZIP?