Android: HTTP संचार में "स्वीकार-एनकोडिंग: gzip" का उपयोग करना चाहिए


109

मैंने JSON डेटा का अनुरोध करने वाले वेबसर्वर के लिए HTTP संचार किया है। मैं इस डेटा स्ट्रीम को संक्षिप्त करना चाहूंगा Content-Encoding: gzip। क्या कोई ऐसा तरीका है जिसे मैं Accept-Encoding: gzipअपने HttpClient में सेट कर सकता हूं? gzipAndroid संदर्भ के लिए खोज HTTP से संबंधित कुछ भी नहीं दिखाती है, जैसा कि आप यहां देख सकते हैं ।


1
Android-WebRequest GZIP और असम्बद्ध प्रतिक्रियाओं का समर्थन करता है, जैसे कि new WebRequest().get().to("http://www.example.com/").askForGzip(true).executeSync()। विशेष रूप से, विधि parseResponse (...) होना चाहिए जो आप देख रहे हैं।
कांव-कांव

जवाबों:


174

आपको यह इंगित करने के लिए 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);
}

7
यह मेरे लिए आवश्यक सभी विवरणों के साथ एक शानदार और बहुत ही उपयोगी उत्तर है। बहुत बहुत धन्यवाद। एक टिप्पणी: addHeader के बजाय मैंने setHeader का उपयोग किया। अगर मैं समझता हूं कि यह मौजूदा "स्वीकार-एनकोडिंग" को अधिलेखित करता है अगर कोई है। निश्चित नहीं है कि कौन सा दृष्टिकोण सही / बेहतर है। किसी मौजूदा हेडर को यह सुनिश्चित करने के लिए कि उसका सही मूल्य है, या इसे मामले में जोड़ने के लिए कि अन्य एक्सेप्ट-एन्कोडिंग हेडर समानांतर में हो सकते हैं।
znq

तुम कहाँ से डाल दिया है?
मिकी डे

7
यह अनुरोध को gzip नहीं करता है, यह केवल सर्वर को बताता है कि आप gzip'd प्रतिक्रिया स्वीकार कर सकते हैं।
जेफरी ब्लाटमैन

1
किसी के लिए भी इसे पाने में परेशानी हो रही है और Google सेवाओं के लिए यहां चल रहे हैं दो मुद्दे हैं, जो मुझे पता लगाने में कुछ समय लगा: (1) कुछ Google सेवाओं के लिए ग्राहक द्वारा प्रदान किए गए उपयोगकर्ता एजेंट स्ट्रिंग की आवश्यकता होती है ताकि स्ट्रिंग gzipको वास्तव में सक्षम किया जा सके। gzip संपीड़न। (2) ध्यान रखें कि सर्वर बहुत छोटा होने पर प्रतिक्रिया को गज़ब नहीं कर सकता है ...
ऋग्वेद

मेरी समस्या यह है कि gzip हेडर कहीं नहीं देखा जा सकता है। मैं सर्वर साइड पर नेटवर्क को सूँघने के लिए Wireshark का उपयोग कर रहा हूं, और मुझे "gzip" हेडर का कोई निशान नहीं दिख रहा है जो मैंने एंड्रॉइड में जोड़ा है ...
Ted

33

यदि आप एपीआई स्तर 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() );

नीप टिप रिव्युअरेस्पेन्स्ट एंड गेटअंगज़िप्ड, इसके अलावा, मुझे EntityUtils.toString (HttpEntity) की प्रतिलिपि बनाने की आवश्यकता है, स्ट्रिंग के रूप में अनजिपीड स्ट्रीम को पार्स करने के लिए
मार्कोस

1
AndroidHttpClient एपीआई स्तर 22 में पदावनत किया गया था।
एलेक्स कुचरेंको

13

मुझे लगता है कि इस लिंक पर कोड का नमूना अधिक दिलचस्प है: ClientGZipContentCompression.java

वे HttpRequestInterceptor और HttpResponseInterceptor का उपयोग कर रहे हैं

अनुरोध के लिए नमूना:

        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
किसी भी कारण से आपको लगता है कि यह अधिक दिलचस्प है?
गौरव अग्रवाल

3
@codingcrow यहां वह है जो आप ढूंढ रहे हैं: इस विशेष मामले में HTTP क्लाइंट को दो प्रोटोकॉल इंटरसेप्टर जोड़कर पारदर्शी सामग्री GZIP संपीड़न के लिए सक्षम बनाया गया है: एक अनुरोध अवरोधक जो सभी स्वीकारोक्ति अनुरोधों और एक प्रतिक्रिया के लिए 'Accept-Encoding: gzip' हेडर जोड़ता है इंटरसेप्टर जो स्वचालित रूप से संपीड़ित प्रतिक्रिया संस्थाओं को एक असम्पीडित डेकोरेटर वर्ग के साथ लपेटकर फैलता है। प्रोटोकॉल इंटरसेप्टर का उपयोग HttpClient इंटरफ़ेस के उपभोक्ता के लिए सामग्री संपीड़न को पूरी तरह से पारदर्शी बनाता है।
क्लूज़िएर डे


GzipDecompressingEntity को android.jar (2.2) में नहीं पाया जा सकता है
imcaptor

1

मैं GZip उपयोग नहीं किया है, लेकिन मुझे लगता है कि आप अपने से इनपुट धारा का उपयोग करना चाहिए HttpURLConnectionया HttpResponseके रूप में GZIPInputStreamहै, और नहीं कुछ विशिष्ट अन्य वर्ग।


HTTPURLConnection ने डिफ़ॉल्ट रूप से gzip चालू कर दिया है। आपको बस यह सुनिश्चित करने की आवश्यकता है कि आपका वेब सर्वर gzip पृष्ठ वापस कर सकता है। developer.android.com/reference/java/net/HttpURLConnection.html मैं ob_start ("ob_gzhandler") का उपयोग करके php से gzip पृष्ठ वापस करने में सक्षम था;
metric152

जब आपके पास कोई उत्तर न हो तो उत्तर न दें!
मार्टिन। मार्टिंसन

0

मेरे मामले में यह इस प्रकार था:

URLConnection conn = ...;
InputStream instream = conn.getInputStream();
String encodingHeader = conn.getHeaderField("Content-Encoding");
if (encodingHeader != null && encodingHeader.toLowerCase().contains("gzip"))
{
    instream = new GZIPInputStream(instream);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.