2010-10-03 18 views
7

Próbuję sparsować plik z Internetu na Androida przy użyciu metody DOM.Obsługa spakowanych treści gzip na Androidzie

Kod w pytaniu:

try { 
    URL url = new URL("https://www.beatport.com/en-US/xml/content/home/detail/1/welcome_to_beatport"); 

    InputSource is = new InputSource(url.openStream()); 

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document document = db.parse(is); 
    document.getDocumentElement().normalize(); 
} catch(Exception e) { 
    Log.v(TAG, "Exception = " + e); 
} 

Ale ja otrzymuję następujący wyjątek:

V/XMLParseTest1( 846):Exception = org.xml.sax.SAXParseException: name expected (position:START_TAG <null>@2:176 in [email protected]) 

Plik jest przekazany do mnie skompresowane. Sprawdziłem obiekt is w debugerze, a jego długość wynosi 6733 bajtów (tak samo jak długość zawartości pliku w nagłówkach odpowiedzi), ale jeśli zapiszę plik na moim dysku twardym z przeglądarki, jego rozmiar wynosi 59114 bajtów. Ponadto, jeśli prześlę go na mój własny serwer, który nie zgłasza XML-ów, gdy je obsługuje, i ustawia adres URL, kod działa dobrze.

Zgaduję, że to, co dzieje się w systemie Android, to próba przeanalizowania spakowanego pliku gzip.

Czy istnieje sposób, aby najpierw rozpakować strumień? Jakieś inne pomysły?

+1

spójrz na ten link http://stackoverflow.com/q/6717165/779408. Jest tam reprezentowana metoda kompresji i dekompresji. – breceivemail

Odpowiedz

20

Możesz zawinąć wynik url.openStream() w GZIPInputStream. np .:

InputSource is = new InputSource(new GZIPInputStream(url.openStream())); 

Aby automatycznie wykryć, kiedy to zrobić, użyj nagłówka HTTP Content-Encoding. np:

URLConnection connection = url.openConnection(); 
InputStream stream = connection.getInputStream(); 
if ("gzip".equals(connection.getContentEncoding())) { 
    stream = new GZIPInputStream(stream)); 
} 
InputSource is = new InputSource(stream); 
+0

Wielkie dzięki. Jeszcze jedno pytanie: czy istnieje sposób, aby dowiedzieć się, czy strumień jest gzipowany? – janosrusiczki

+0

Dziękuję również za edycję problemu z automatyczną detekcją. – janosrusiczki

3

Domyślnie ta implementacja HttpURLConnection wnosi serwery wykorzystują kompresję gzip. Ponieważ getContentLength() zwraca liczbę przesłanych bajtów , nie można użyć tej metody do przewidywania, jak wiele bajtów można odczytać z getInputStream(). Zamiast tego przeczytaj ten strumień , aż się wyczerpie: gdy read() zwróci -1. kompresja gzip może być wyłączone przez ustawienie dopuszczalne kodowania we wniosku nagłówka:

urlConnection.setRequestProperty ("Accept-Encoding", "tożsamość");

, więc nic nie trzeba robić.

Powiązane problemy