【问题标题】:Android: HTTP communication should use "Accept-Encoding: gzip"Android:HTTP 通信应使用“Accept-Encoding: gzip”
【发布时间】:2009-10-15 16:10:01
【问题描述】:

我与请求 JSON 数据的网络服务器进行了 HTTP 通信。我想用Content-Encoding: gzip 压缩这个数据流。有没有办法可以在我的 HttpClient 中设置Accept-Encoding: gzip?在 Android References 中搜索 gzip 并没有显示任何与 HTTP 相关的内容,如您所见 here

【问题讨论】:

  • Android-WebRequest 自动支持 GZIP 和未压缩响应,例如与new WebRequest().get().to("http://www.example.com/").askForGzip(true).executeSync()。具体来说,parseResponse(...) 方法应该是您要查找的方法。

标签: android http gzip content-encoding


【解决方案1】:

您应该使用 http 标头来指示连接可以接受 gzip 编码的数据,例如:

HttpUriRequest request = new HttpGet(url);
request.addHeader("Accept-Encoding", "gzip");
// ...
httpClient.execute(request);

检查内容编码的响应:

InputStream instream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
    instream = new GZIPInputStream(instream);
}

【讨论】:

  • 这是一个很棒且非常有用的答案,包含我需要的所有细节。非常感谢。一条评论:我使用 setHeader 而不是 addHeader。据我了解,如果有的话,这会覆盖现有的“接受编码”。不确定哪种方法是正确/更好的。覆盖现有的标头以确保它具有正确的值,或者在可能有其他并行的 Accept-Encoding 标头的情况下添加它。
  • 那你把插播放在哪里?
  • 这不会对请求进行 gzip 压缩,它只会告诉服务器您可以接受 gzip 的响应。
  • 对于任何也无法启动和运行谷歌服务的人,这里有两个问题,我花了很长时间才发现:(1)一些谷歌服务需要用户代理字符串由客户端包含字符串gzipreally 启用gzip 压缩。 (2) 请记住,如果响应太小,服务器可能不会压缩响应...
  • 我的问题是 gzip 标头无处可见。我正在使用 Wireshark 嗅探服务器端的网络,但我没有看到我在 android 中添加的“gzip”标头的任何痕迹......
【解决方案2】:

如果您使用的是 API 级别 8 或更高级别,则为 AndroidHttpClient

它有一些辅助方法,例如:

public static InputStream getUngzippedContent (HttpEntity entity)

public static void modifyRequestToAcceptGzipResponse (HttpRequest request)

导致代码更加简洁:

AndroidHttpClient.modifyRequestToAcceptGzipResponse( request );
HttpResponse response = client.execute( request );
InputStream inputStream = AndroidHttpClient.getUngzippedContent( response.getEntity() );

【讨论】:

  • 很好地提示 modifyRequest 和 getUngzipped,另外,我需要复制 EntityUtils.toString(HttpEntity) 以将 ungzipeed 流解析为字符串
  • AndroidHttpClient 在 API 级别 22 中已弃用。
【解决方案3】:

我认为这个链接上的代码示例更有趣: ClientGZipContentCompression.java

他们正在使用 HttpRequestInterceptorHttpResponseInterceptor

请求样品:

        httpclient.addRequestInterceptor(new HttpRequestInterceptor() {

            public void process(
                    final HttpRequest request,
                    final HttpContext context) throws HttpException, IOException {
                if (!request.containsHeader("Accept-Encoding")) {
                    request.addHeader("Accept-Encoding", "gzip");
                }
            }

        });

答案示例:

        httpclient.addResponseInterceptor(new HttpResponseInterceptor() {

            public void process(
                    final HttpResponse response,
                    final HttpContext context) throws HttpException, IOException {
                HttpEntity entity = response.getEntity();
                Header ceheader = entity.getContentEncoding();
                if (ceheader != null) {
                    HeaderElement[] codecs = ceheader.getElements();
                    for (int i = 0; i < codecs.length; i++) {
                        if (codecs[i].getName().equalsIgnoreCase("gzip")) {
                            response.setEntity(
                                    new GzipDecompressingEntity(response.getEntity()));
                            return;
                        }
                    }
                }
            }

        });

【讨论】:

  • 您认为它更有趣的原因有哪些?
  • @codingcrow 这就是您要查找的内容:在这种特殊情况下,通过添加两个协议拦截器使 HTTP 客户端能够进行透明内容 GZIP 压缩:一个添加了“Accept-Encoding”的请求拦截器: gzip' 所有传出请求的标头和一个响应拦截器,它通过用解压缩的装饰器类包装压缩的响应实体来自动扩展压缩的响应实体。协议拦截器的使用使内容压缩对 HttpClient 接口的使用者完全透明。
  • GzipDecompressingEntity 在 android.jar (2.2) 中找不到
【解决方案4】:

我没有使用 GZip,但我认为您应该使用来自 HttpURLConnectionHttpResponse 的输入流作为 GZIPInputStream,而不是使用其他特定的类。

【讨论】:

【解决方案5】:

在我的情况下是这样的:

URLConnection conn = ...;
InputStream instream = conn.getInputStream();
String encodingHeader = conn.getHeaderField("Content-Encoding");
if (encodingHeader != null && encodingHeader.toLowerCase().contains("gzip"))
{
    instream = new GZIPInputStream(instream);
}

【讨论】:

    猜你喜欢
    • 2019-11-08
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多