Apache Commons HttpClient 是不是支持 GZIP?

Posted

技术标签:

【中文标题】Apache Commons HttpClient 是不是支持 GZIP?【英文标题】:Does Apache Commons HttpClient support GZIP?Apache Commons HttpClient 是否支持 GZIP? 【发布时间】:2011-02-16 03:38:15 【问题描述】:

库 Apache Commons HttpClient 是否支持 Gzip?我们想在我们的 Apache 服务器上使用启用 gzip 压缩来加速客户端/服务器通信(我们有一个 php 页面,允许我们的 android 应用程序与服务器同步文件)。

【问题讨论】:

【参考方案1】:

它不支持这种开箱即用的功能,而且似乎不太可能将其添加到 HttpClient 3.x 中(请参阅相当讨厌的 JIRA 问题here)。但是,您可以通过添加自定义请求阅读器和手动请求/响应流处理来实现这一点,分层在基本库之上,但这很繁琐。

您似乎可以使用 HttpClient 4 来做到这一点,但并非不费吹灰之力。

相当粗制滥造,如果你问我,这东西真的应该比它更容易。

【讨论】:

@karim79:我已经放弃了 HttpClient 由任何掌握现实的人维护的希望(好像 HttpClient 4 API 没有足够的证据)。【参考方案2】:

Apache HttpClient 4.1 支持开箱即用的内容压缩以及许多以前被认为超出范围的其他功能。

【讨论】:

如何将其从盒子中取出? 在 4.5.3 中,只需通过 HttpClientBuilder.create().build() 使用客户端,它将为您处理所有 gzip 请求和响应解压。【参考方案3】:

如果您的服务器能够提供 GZIPped 内容,那么您只需使用 Apache Http 客户端 4.1 即可

org.apache.http.impl.client.ContentEncodingHttpClient

这是DefaultHttpClient的子类。

此客户端还将添加标头,表明它接受 GZIPped 内容。

【讨论】:

在 HttpClient 4.2.1 中,ContentEncodingHttpClient 已被弃用;鼓励用户使用 DecompressingHttpClient,见hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/… @Hbf 也已弃用。 从 4.3 开始,应该使用HttpClientBuilder(而不是ContentEncodingHttpClientDecompressingHttpClient)。 使用HttpClientBuilder,您是否必须调用构建器上的任何特定方法才能启用gzip?还是您根本不必打电话给disableContentCompression() 不,压缩是自动启用的。我用4.5.3试了一下,用wireshark抓取请求响应:请求中自动添加了“Accept-Encoding: gzip,deflate”头,可以自动解压响应内容。【参考方案4】:

Custom Protocol Interceptors 也可能有帮助。

免责声明:我还没有尝试过。

【讨论】:

【参考方案5】:

它不支持开箱即用,但您可以通过调用将返回的HttpResponse 的实体转换为未压缩的实体

val entity = new GzipDecompressingEntity(response.getEntity)

然后像往常一样继续使用entity.getContent

【讨论】:

【参考方案6】:

这是使用 java apache-http-client 库的示例 scala 代码

 def createCloseableHttpClient(): CloseableHttpClient = 
    val builder: HttpClientBuilder = HttpClientBuilder.create
    val closableClient = builder.build()
    closableClient
  

  def postData(data: String): Unit = 
    val entity = EntityBuilder.create()
      .setText(data)
      .setContentType(ContentType.TEXT_PLAIN)
      .gzipCompress()
      .build()
    val post = new HttpPost(postURL + endPoint)
    post.setEntity(entity)
    post.setHeader("Content-Type", "application/gzip")
    val client = createCloseableHttpClient()
    client.execute(post)
    client.close()
  

【讨论】:

【参考方案7】:

自 4.1 起,Apache HttpClients 处理请求和响应压缩。

您无需压缩请求,无需在请求标头中设置任何“Accept-Encoding”。 它也会自动处理响应解压,无需处理响应解压。 到 4.3 为止,它可以处理 gzip 和 deflate。您可以查看ResponseContentEncoding api doc here。

只需使用:

HttpClients.custom()

使用:

HttpClientBuilder.create()

如果你想签入库转到HttpClientBuilder,它使用RequestAcceptEncoding & ResponseContentEncoding

您可以通过“disableContentCompression()”禁用它

HttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .disableContentCompression() //this disables compression
                .build();

请确保如果您添加任何可以覆盖的拦截器,请谨慎使用。

HttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .setHttpProcessor(httpprocessor) //this interceptor can override your compression.
                .build();

【讨论】:

【参考方案8】:

对于那些(像我一样)由于其他原因无法更新到 Apache 4.xx 并且需要拥有他们的 Apache 的人(顺便说一下,下面首先为 4.3.6 版本实现,但显然不支持“开箱即用”这可能是当然的,因为我们总是使用 custom 那些对我们的 httpclients 有其他特定要求的[“开箱即用”当然可以,如果您完全了解最新信息并且可以接受这个概念实际上会暗示 - 例如,默认重试策略、SSL 主机名验证、默认超时等对我们没有用 - 如果您改用自定义,则 必须 了解你在做什么,从长远来看,这总是更好的......?])。无论如何,该解决方案也适用于 4.x.x 之前的版本——我在上面 Garry 的良好响应之后的示例行中添加了更多内容。使用 maven 构建,并在一般情况下容纳压缩响应,我已经添加了

  <dependency>
      <groupId>org.brotli</groupId>
      <artifactId>dec</artifactId>
      <version>0.1.2</version>
  </dependency>

到我的 pom.xml。然后为了处理所有这三种常见的压缩方法(gzip、deflate 和 brotli),我在设置自定义 Apache HttpClient 时添加了拦截器 - 如下所示:

private static final String GZIP = "gzip";
private static final String DEFLATE = "deflate";
private static final String BR = "br";
private static final String ACCEPT_ENCODING = "Accept-Encoding";
private static final String SUPPORTED_COMPRESSION_VARIANTS = new StringBuilder(GZIP).append(COMMA_SPACE).append(DEFLATE).append(COMMA_SPACE).append(BR).toString();
private static final String COMMA_SPACE = ", ";
..
                   HttpClients.custom()..
                   .addInterceptorFirst((HttpRequestInterceptor) (request, context) ->  // add accepting compressed headers _always_
                    if (!request.containsHeader(ACCEPT_ENCODING)) 
                        request.addHeader(ACCEPT_ENCODING, SUPPORTED_COMPRESSION_VARIANTS);
                    
                    )
                    .addInterceptorFirst((HttpResponseInterceptor) (response, context) -> 
                    HttpEntity entity = response.getEntity();
                    Header ceheader = entity != null ? entity.getContentEncoding() : null;
                    if (ceheader != null) 
                        HeaderElement[] codecs = ceheader.getElements();
                        for (int i = 0; i < codecs.length; i++) 
                            if (codecs[i].getName().equalsIgnoreCase(GZIP))  // handling gzip
                                response.setEntity(new GzipDecompressingEntity(response.getEntity()));
                             else if (codecs[i].getName().equalsIgnoreCase(DEFLATE))  // handling deflate
                                response.setEntity(new DeflateDecompressingEntity(response.getEntity()));
                             else if (codecs[i].getName().equalsIgnoreCase(BR))  // handling brotli
                                try (BufferedReader br =
                                             new BufferedReader(new InputStreamReader(new BrotliInputStream(response.getEntity().getContent())))) 
                                     response.setEntity(new StringEntity(br.lines().collect(Collectors.joining())));
                                
                            
                        
                    
                  ).build();

所以 - 这些的接受标头将始终添加到传出请求中,并且压缩响应由响应拦截器处理。工作正常。

【讨论】:

以上是关于Apache Commons HttpClient 是不是支持 GZIP?的主要内容,如果未能解决你的问题,请参考以下文章

commons-httpclient 和 httpclient 之间有啥关系,都来自 apache

httpClient 保持session

tomcat下程序出现org.apache.commons.httpclient.HttpMethodDirector的错误

Java通过httpclient获取cookie模拟登录

请问有org.apache.commons.httpclient.HttpClient.*的jar是哪个?该去哪儿下载

获取Cookie