2010-10-03 21 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”);

所以没什么需要做的。