Android:HTTP通信は「Accept-Encoding:gzip」を使用する必要があります


109

JSONデータを要求するWebサーバーへのHTTP通信を使用しています。このデータストリームをで圧縮しContent-Encoding: gzipます。Accept-Encoding: gzipHttpClientで設定できる方法はありますか?検索gzipあなたが見ることができるようにAndroidの参考文献には、HTTPに関連したものを表示されませんここに


1
Android-WebRequestは、GZIPおよび非圧縮応答を自動的にサポートしnew WebRequest().get().to("http://www.example.com/").askForGzip(true).executeSync()ます。具体的には、メソッドparseResponse(...)を探しているはずです。
2014年

回答:


174

接続がgzipエンコードされたデータを受け入れることができることを示すには、httpヘッダーを使用する必要があります。例:

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);
}

7
これは、私が必要とするすべての詳細を含む、非常に役立つ素晴らしい回答です。どうもありがとう。1つのコメント:addHeaderの代わりに、setHeaderを使用しました。私が理解しているところによると、これは既存の「Accept-Encoding」があれば上書きします。どちらのアプローチが正しい/より良いかわかりません。既存のヘッダーを上書きして適切な値を設定するか、他のAccept-Encodingヘッダーが並行して存在する可能性がある場合に追加します。
znq 2009年

では、インストリームをどこに配置しますか?
マイキー

7
これはリクエストをgzipするのではなく、gzipされた応答を受け入れることができることをサーバーに伝えるだけです。
ジェフリーブラットマン、2011年

1
これを取得してgoogleサービスを実行するのに問題がある人のために、ここで2つの問題を見つけました。これにはかなりの時間がかかりました。(1)一部のgoogleサービスでは、クライアントが提供するユーザーエージェント文字列にgzip実際に有効にする文字列を含める必要があります。gzip圧縮。(2)応答が小さすぎる場合、サーバーは応答をgzipしない可能性があることに注意してください...
svenを

私の問題は、gzipヘッダーが表示されないことです。Wiresharkを使用してサーバー側のネットワークを盗聴していて、Androidで追加した「gzip」ヘッダーの痕跡が見当たらない...
Ted

33

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)をコピーして、圧縮解除されたストリームを文字列として解析する必要がありました
Marcos Vasconcelos

1
AndroidHttpClientはAPIレベル22で廃止されました
アレックスKucherenko

13

このリンクのコードのサンプルはより興味深いと思います: 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;
                        }
                    }
                }
            }

        });

1
面白いと思う理由はありますか?
Gaurav Agarwal

3
@codingcrowこれがあなたが探しているものです:この特定のケースでは、HTTPクライアントは2つのプロトコルインターセプターを追加することで透過的なコンテンツGZIP圧縮が可能になります。圧縮された応答エンティティーを非圧縮のデコレータークラスでラップすることによって自動的に展開するインターセプター。プロトコルインターセプターを使用すると、HttpClientインターフェイスのコンシューマーに対してコンテンツの圧縮が完全に透過的になります。
クロージエール


GzipDecompressingEntityがandroid.jar(2.2)に見つかりません
imcaptor

1

私は、GZIPを使用していないが、私はあなたからの入力ストリームを使用する必要があることを前提としていますHttpURLConnectionHttpResponseなどGZIPInputStream、いくつかの特定の他のクラス、およびありません。


HTTPURLConnectionでは、デフォルトでgzipがオンになっています。Webサーバーがgzipページを返すことができることを確認する必要があるだけです。 developer.android.com/reference/java/net/HttpURLConnection.html ob_start( "ob_gzhandler");を使用して、phpからgzipページを返すことができました。
metric152 2012

答えがないときは答えないで!
Martin.Martinsson 2018年

0

私の場合、それはこのようなものでした:

URLConnection conn = ...;
InputStream instream = conn.getInputStream();
String encodingHeader = conn.getHeaderField("Content-Encoding");
if (encodingHeader != null && encodingHeader.toLowerCase().contains("gzip"))
{
    instream = new GZIPInputStream(instream);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.