【问题标题】:Decompressing a gzipped http response解压缩 gzip 后的 http 响应
【发布时间】:2013-05-17 01:32:08
【问题描述】:

Java 开发人员您好。我收到一个包含如下标题和正文的响应,但是当我尝试使用下面的代码解压缩它时,它会失败并出现以下异常:

java.io.IOException:不是 GZIP 格式

回应:

HTTP/1.1 200 正常 内容类型:文本/xml;字符集=utf-8 内容编码:gzip 服务器:码头(6.1.x) ▼ ═UMs¢0►=7┐ép?╙6-C╚$╢gΩ↓╟±╪₧∟zS╨╓╓♦$FÆ╒÷▀G┬╚╞8N≤╤Cf°►╦█╖╗o ↨æJÄ+`:↓2 ♣»└√S▬L&?∙┬_)U╔|♣%ûíyk_à\,æ] hⁿ?▀xΓ∟o╜4♫ù\#MAHG?┤(Q¶╞⌡▌Ç?▼ô[7Fí¼↔ φ☻I%╓╣Z♂?¿↨F;x|♦o/A╬♣╘≡∞─≤╝╘U∙♥0☺æ?|J%à{(éUmHµ %σl┴▼Ç9♣┌Ç ?♫╡5╠yë~├╜♦íi♫╥╧ ╬û?▓ε?╞┼→RtGqè₧ójWë♫╩∞j05├╞┘|>┘º∙↑j╪2┐|= ÷² eY\╛P?#5wÑqc╙τ♦▓½Θt£6q∩?┌4┼t♠↕=7æƒ╙?╟|♂;║)∩÷≈═^╛{v⌂┌∞◄>6ä╝|

代码:

byte[] b=  IOUtils.toByteArray(sock.getInputStream());

ByteArrayInputStream bais = new ByteArrayInputStream(b);
GZIPInputStream gzis = new GZIPInputStream(bais);
InputStreamReader reader = new InputStreamReader(gzis);
BufferedReader in = new BufferedReader(reader);

String readed;
while ((readed = in.readLine()) != null) {
    System.out.println("read:  "+readed);
}

请指教。

谢谢,

普雷迪普

【问题讨论】:

  • sock 是什么?如果是套接字,您应该知道标头和其他一些东西没有被 gzip 压缩。只有响应正文是。

标签: java gzip


【解决方案1】:

MIME 标头不是 GZIP 格式,而是纯文本。您必须先阅读该内容,然后才能解压缩流。

另外,为什么不直接使用这个:

InputStream in = sock.getInputStream();
readHeader(in);
InputStream zin = new GZIPInputStream(in);

【讨论】:

  • 你能告诉我你读标题是什么意思吗? readHeader(in); ?
  • 我的意思是当你得到一个文件时,你会得到一个标题,上面写着“Content-type: text/html”之类的内容,其中包含纯文本的元数据。每个元数据元素由换行符分隔,整个标头以 2 个换行符结尾,然后数据开始。 en.wikipedia.org/wiki/MIME#MIME_headers
【解决方案2】:

所有这些都有库。例如,您可以使用Apache HTTP Components,或者您可以阅读其开源代码以了解其功能。至少,请阅读the relevant specification.

【讨论】:

    【解决方案3】:

    我第二个 bmarguiles 的回答。

    只有body(RFC中的response-body)被压缩,所以你只需要解压\r\n\r\n之后的部分。

    一般来说,你可以通过双CRLF将响应减半,然后只解压缩后半部分。

    【讨论】: