Обработка содержимого gzipped на Android

Я пытаюсь проанализировать файл из Интернета на Android с помощью метода DOM.

Этот код:

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 java.io.InputStreamReader@43ea4538) 

Файл передается мне gzipped. Я проверил объект is в отладчике, и его длина составляет 6733 байта (такая же, как длина содержимого файла в заголовках ответов), однако, если я сохраню файл на своем жестком диске в браузере, его размер составляет 59114 байт. Кроме того, если я загружу его на свой собственный сервер, который не gzip XML-s, когда он их обслуживает, и установите URL-адрес, код будет работать нормально.

Я предполагаю, что происходит, что Android пытается разобрать gzipped поток.

Есть ли способ сначала разархивировать поток? Любые другие идеи?

Вы можете обернуть результат url.openStream() в GZIPInputStream . например:

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

Чтобы автоматически определить, когда это сделать, используйте HTTP-заголовок Content-Encoding. например:

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

По умолчанию эта реализация HttpURLConnection требует, чтобы серверы использовали сжатие gzip. Поскольку getContentLength () возвращает количество переданных байтов, вы не можете использовать этот метод для прогнозирования того, сколько байтов может быть прочитано из getInputStream (). Вместо этого прочитайте этот поток до тех пор, пока он не будет исчерпан: когда read () возвращает -1. Сжатие Gzip можно отключить, установив приемлемые кодировки в заголовке запроса:

UrlConnection.setRequestProperty («Accept-Encoding», «identity»);

Поэтому ничего не нужно делать.