2010-03-19 15 views
8

Próbuję zdekompresować odpowiedź GZIPed HTTP za pomocą GZIPInputStream. Jednak zawsze mam ten sam wyjątek przy próbie odczytania strumienia: java.util.zip.ZipException: invalid bit length repeatDekompresuj odpowiedź GZIPed HTTP w języku Java

Moje żądania HTTP Header:

GET www.myurl.com HTTP/1.0\r\n 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6\r\n 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n 
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3\r\n 
Accept-Encoding: gzip,deflate\r\n 
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\r\n 
Keep-Alive: 115\r\n 
Connection: keep-alive\r\n 
X-Requested-With: XMLHttpRequest\r\n 
Cookie: Some Cookies\r\n\r\n 

Pod koniec nagłówka odpowiedzi HTTP, mam path=/Content-Encoding: gzip, a następnie gziped odpowiedzi .

Próbowałem 2 podobieństw kody do dekompresji:

UPDATE: W poniższych kodów, tBytes = (the string after 'path=/Content-Encoding: gzip').getBytes();

GZIPInputStream gzip = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 

StringBuffer szBuffer = new StringBuffer(); 

byte tByte [] = new byte [1024]; 

while (true) 
{ 
    int iLength = gzip.read (tByte, 0, 1024); // <-- Error comes here 

    if (iLength < 0) 
     break; 

    szBuffer.append (new String (tByte, 0, iLength)); 
} 

A ten, który mam na tym forum:

InputStream  gzipStream = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 
Reader   decoder = new InputStreamReader (gzipStream, "UTF-8");//<- I tried ISO-8859-1 and get the same exception 
BufferedReader buffered = new BufferedReader (decoder); 

Chyba to jest błąd kodowania.

poważaniem,

bill0ute

Odpowiedz

9

Nie pokazuj, jak uzyskać tBytes że używasz do utworzenia strumienia gzip tutaj:

GZIPInputStream gzip = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 

Jednym z wyjaśnień jest to, że jesteś w tym cała odpowiedź HTTP w tBytes. Zamiast tego powinna to być tylko zawartość po nagłówkach HTTP.

Kolejnym wyjaśnieniem jest odpowiedź: chunked.

edycja: Dane są pobierane za linią kodowania treści jako treść wiadomości. Jednak zgodnie ze specyfikacją HTTP 1.1 pola nagłówka nie są w żadnej określonej kolejności, więc jest to bardzo niebezpieczne.

Jak wyjaśniono w tej części HTTP specification, treść wiadomości żądania lub odpowiedzi nie przyjść po określonym polu nagłówka ale po pierwszym pustym wierszu:

życzenie (odcinek 5) i odpowiedzi (sekcja 6) wiadomości używają ogólnego formatu wiadomości RFC 822 [9] dla przesyłających encje (ładunek wiadomość). Oba typy komunikatów składają się z pól nagłówka, zerowych lub większej liczby nagłówków (znanych również jako "nagłówków"), pustej linii (tj. Linii bez niczego poprzedzającej CRLF) wskazującej koniec nagłówka pola i ewentualnie treść wiadomości.

Nadal nie pokazać, jak dokładnie komponować tBytes, ale w tym momencie myślę, że błędnie tym pustą linię na danych, które starają się rozpakować. Treść wiadomości rozpoczyna się po znakach CRLF z pustej linii.

Czy mogę zaproponować, aby zamiast tego użyć biblioteki httpclient, aby wyodrębnić treść wiadomości?

+0

Witam Wim. Dzięki za odpowiedź. Zaktualizowałem wiadomość, aby wyjaśnić, w jaki sposób uzyskuję tBytes. Nie sądzę, że odpowiedź jest porwana, ponieważ istnieje nagłówek Content-Length. Ale nie jestem pewien. bill0ute – bill0ute

+0

Witaj Wim. Próbuję użyć pakietu HttpClient, ale nie mogę znaleźć dokumentu Java. Dostaję tylko przykłady. Czy możesz podać mi przykład połączenia z gniazdem i wysłać żądanie pobrania? Dzięki – bill0ute

+0

Zapoznaj się z samouczkiem, jest to prosty przykład uzyskania ciała odpowiedzi dla HTTP GET: http://hc.apache.org/httpclient-3.x/tutorial.html W twoim przypadku będziesz chciał przetwarzaj 'responseBody' tak jak teraz przetwarzaj' tBytes'. –

1

Cóż, jest problem, który widzę tutaj;

int iLength = gzip.read (tByte, 0, 1024); 

Skorzystaj z poniższego, aby to naprawić;

 byte[] buff = new byte[1024]; 
byte[] emptyBuff = new byte[1024]; 
          StringBuffer unGzipRes = new StringBuffer(); 

          int byteCount = 0; 
          while ((byteCount = gzip.read(buff, 0, 1024)) > 0) { 
           // only append the buff elements that 
           // contains data 
           unGzipRes.append(new String(Arrays.copyOf(
             buff, byteCount), "utf-8")); 

           // empty the buff for re-usability and 
           // prevent dirty data attached at the 
           // end of the buff 
           System.arraycopy(emptyBuff, 0, buff, 0, 
             1024); 
          } 
Powiązane problemy