2010-10-03 43 views
7

我想使用DOM方法從Android上的web上解析文件。在Android上處理gzip內容

有問題的代碼是:

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

但我發現了以下異常:

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

該文件被交給我gzip壓縮。我在調試器中檢查了is對象,其長度爲6733字節(與響應頭文件中的文件內容長度相同),但是如果從瀏覽器將文件保存到我的硬盤驅動器,它的大小爲59114字節。此外,如果我將它上傳到我自己的服務器,而服務器在服務它們時不會gzip XML-s,並且設置了URL,那麼代碼運行得很好。

我猜測會發生什麼是Android試圖解析gzipped流。

有沒有辦法先解壓縮流?任何其他想法?

+1

看看這個鏈接http://stackoverflow.com/q/6717165/779408。在那裏表示壓縮和解壓縮方法。 – breceivemail 2013-01-15 10:38:43

回答

20

您可以將url.openStream()的結果包含在GZIPInputStream中。例如:

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

要自動檢測何時執行此操作,請使用Content-Encoding HTTP標頭。例如:

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

非常感謝。還有一個問題:有沒有辦法找出一個流是否被壓縮? – janosrusiczki 2010-10-03 02:32:48

+0

也感謝您對自動檢測問題的編輯。 – janosrusiczki 2010-10-11 12:27:08

3

默認情況下,這個實現HttpURLConnection類的請求 服務器使用gzip壓縮。由於getContentLength()返回傳輸的字節數 ,因此不能使用該方法來預測如何從getInputStream()讀取多個字節。相反,讀取 流直到它耗盡:read()返回-1。 Gzip壓縮 可以通過在請求中設置可接受的編碼來禁用 頭文件:

urlConnection.setRequestProperty(「Accept-Encoding」,「identity」);

所以沒什麼需要做的。