用Java解压缩GZIPped HTTP响应

时间:2010-03-19 00:07:34

标签: java gzip httpresponse compression

我正在尝试使用GZIPInputStream解压缩GZIPed HTTP响应。但是,当我尝试阅读流时,我总是遇到相同的异常:java.util.zip.ZipException: invalid bit length repeat

我的HTTP请求标头:

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

在HTTP响应标头的末尾,我得到path=/Content-Encoding: gzip,然后是gziped响应。

我尝试了2个类似的代码来解压缩:

更新:在以下代码中,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));
}

这是我在这个论坛上得到的那个:

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

我猜这是编码错误。

致以最诚挚的问候,

bill0ute

2 个答案:

答案 0 :(得分:9)

您没有在此处显示如何获得用于设置gzip流的tBytes

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

一种解释是您将整个HTTP响应包含在tBytes中。相反,它应该只是HTTP标头之后的内容。

另一种解释是答复为chunked

编辑:您将内容编码行之后的数据作为邮件正文。但是,根据HTTP 1.1规范,头字段没有任何特定顺序,因此这非常危险。

正如HTTP specification的这一部分所述,请求或响应的邮件正文不是在特定标题字段之后,而是在第一个空行之后的

  

要求(第5节)和回应   (第6节)消息使用通用   RFC 822 [9]的消息格式   转移实体(有效载荷)   消息)。两种类型的消息   由起始线组成,零或更多   标题字段(也称为   “标题”),一个空行(即a   在CRLF之前没有任何内容的行   表示标题的结尾   字段,可能还有消息体。

你仍然没有显示你是如何撰写tBytes的,但是在这一点上我认为你错误地在你试图解压缩的数据中包含空行。消息正文在空行的CRLF字符后开始。

我建议您使用httpclient库来提取邮件正文吗?

答案 1 :(得分:1)

我可以在这里找到问题;

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

使用以下内容来解决问题;

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