对 HttpClient[Java] 处理 gzip 响应有点困惑
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21482965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A bit confused about HttpClient[Java] handling gzip responses
提问by iCodeLikeImDrunk
My application makes a http request to some api service, that service returns a gzipped response. How can I make sure that the response is indeed in gzip format? I'm confused at why after making the request I didn't have to decompress it.
我的应用程序向某个 api 服务发出 http 请求,该服务返回一个 gzipped 响应。如何确保响应确实是 gzip 格式?我很困惑为什么在提出请求后我不必解压缩它。
Below is my code:
下面是我的代码:
public static String streamToString(InputStream stream) {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
logger.error("Error while streaming to string: {}", e);
} finally {
try { stream.close(); } catch (IOException e) { }
}
return sb.toString();
}
public static String getResultFromHttpRequest(String url) throws IOException { // add retries, catch all exceptions
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet;
HttpResponse httpResponse;
InputStream stream;
try {
httpGet = new HttpGet(url);
httpGet.setHeader("Content-Encoding", "gzip, deflate");
httpResponse = httpclient.execute(httpGet);
logger.info(httpResponse.getEntity().getContentEncoding());
logger.info(httpResponse.getEntity().getContent());
if (httpResponse.getStatusLine().getStatusCode() == 200) {
stream = httpResponse.getEntity().getContent();
return streamToString(stream);
}
} catch (IllegalStateException e) {
logger.error("Error while trying to access: " + url, e);
}
return "";
}
Maybe it is decompressing it automatically, but I would like to see some indication of that at least.
也许它正在自动解压缩它,但我希望至少看到一些迹象。
采纳答案by Prabhat Kumar
Hi I am late but this answer might by used who is facing same issue. By default content is decompressed in the response. So, you have to disable the default compression using following code:
嗨,我迟到了,但是这个答案可能会被遇到同样问题的人使用。默认情况下,内容在响应中解压缩。因此,您必须使用以下代码禁用默认压缩:
CloseableHttpClient client = HttpClients.custom()
.disableContentCompression()
.build();
HttpGet request = new HttpGet(urlSring);
request.setHeader(HttpHeaders.ACCEPT_ENCODING, "gzip");
CloseableHttpResponse response = client.execute(request, context);
HttpEntity entity = response.getEntity();
Header contentEncodingHeader = entity.getContentEncoding();
if (contentEncodingHeader != null) {
HeaderElement[] encodings =contentEncodingHeader.getElements();
for (int i = 0; i < encodings.length; i++) {
if (encodings[i].getName().equalsIgnoreCase("gzip")) {
entity = new GzipDecompressingEntity(entity);
break;
}
}
}
String output = EntityUtils.toString(entity, Charset.forName("UTF-8").name());
回答by Elliott Frisch
I think you want to use DecompressingHttpClient(or the new HttpClientBuilder- which adds that header by default, don't call disableContentCompression - I don't think DefaultHttpClient
supports compression by default). The client needs to send an Accept-Encodingheader, Content-Encoding comes from the server response.
我认为您想使用DecompressingHttpClient(或新的HttpClientBuilder- 默认情况下添加该标头,不要调用 disableContentCompression - 我认为DefaultHttpClient
默认情况下不支持压缩)。客户端需要发送一个Accept-Encoding头,Content-Encoding 来自服务器响应。
回答by ok2c
httpResponse.getEntity().getContentEncoding()
You can find out whether or not an entity requires decompression by examining its Content-Encoding
header. This header will be rewritten (or removed) in case of automatic content decompression.
您可以通过检查其Content-Encoding
标头来确定实体是否需要解压缩。在自动内容解压缩的情况下,此标头将被重写(或删除)。
回答by Garry
Since 4.1, Apache HttpClients handles request and response compression. You can check the example in another answer here.
从 4.1 开始,Apache HttpClients 处理请求和响应压缩。您可以在此处查看另一个答案中的示例。
Still in case you want to check whether the response was compressed or not. You can print the class of the entity.
以防万一您想检查响应是否被压缩。您可以打印实体的类。
HttpResponse httpResponse = client.execute(request);
HttpEntity httpEntity = httpResponse.getEntity();
System.out.println(httpEntity.getClass().getName());
In case of gzip
the output will be org.apache.http.client.entity.GzipDecompressingEntity
& for deflate
its org.apache.http.client.entity.DecompressingEntity
如果gzip
输出将是org.apache.http.client.entity.GzipDecompressingEntity
& 对于deflate
它的org.apache.http.client.entity.DecompressingEntity