1

我们正在使用 packetbeat,这是一种用于捕获 http 请求和 http 响应的网络数据包分析器工具。Packebeat 以 json 格式保存此数据包事件。当服务器支持 gzip 压缩时,问题就出现了,packetbeat 无法解压缩内容并将其直接保存为 gzip 内容为 json 属性。如您所见(注意:json已被简化);

{
 {
     ... ,
     "content-type":"application/json;charset=UTF-8",
     "transfer-encoding":"chunked",
     "content-length":6347,
     "x-application-context":"proxy-service:pre,native:8080",
     "content-encoding":"gzip",
     "connection":"keep-alive",
     "date":"Mon, 18 Dec 2017 07:18:23 GMT"
 },
 "body": "\u001f\ufffd\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003\ufffd]k\ufffd\u0014DZ\ufffd/\ufffdYI\ufffd#\ufffd*\ufffdo\ufffd\ufffd\ufffd\u0002\t\u0010^\ufffd\u001c\u000eE=\ufffd{\ufffdb\ufffd\ufffdE\ufffd\ufffdC\ufffd\ufffdf\ufffd,\ufffd\u003e\ufffd\ufffd\ufffd\u001ef\u001a\u0008\u0005\ufffd\ufffdg\ufffd\ufffd\ufffdYYU\ufffd\ufffd;\ufffdoN\ufffd\ufffd\ufffdg\ufffd\u0011UdK\ufffd\u0015\u0015\ufffdo\u000eH\ufffd\u000c\u0015Iq\ndC\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd ... "
}

我们正在考虑预处理数据包 json 文件以解压缩内容。有人可以告诉我我需要什么来使用 java 解压缩压缩的“body”json 属性吗?

4

2 回答 2

3

您的数据已不可恢复地损坏。一般来说,我建议使用 Base64 编码来传输打包成 JSON 的二进制数据,但您可以在 JSON String中的二进制数据中阅读可能的替代方案。如果你喜欢实验,比 Base64 更好的东西。

否则,理论上你可以使用一个变体String.getBytes()来获取一个字节数组,并将结果包装到提到的(在另一个答案中)流中:

byte bodyBytes[]=body.getBytes();
ByteArrayInputStream bais=new ByteArrayInputStream(bodyBytes);
GZipInputStream gis=new GZipInputStream(bais);
<do something with gis here, perhaps use an additional DataInputStream>

除了字符串(这通常不是一个好主意)之外,这是您解压缩 gzip 压缩的字节数组的方式。
然而,有效的 gzip 数据以幻数 0x1F,0x8B 开头(参见Wikipedia,或者您也可以挖掘实际规范)。您的数据以 0x1F(该\u001F部分)开头,但以\ufffdUnicode 字符继续,这是一个替换字符(再次参见Wikipedia)。
某些工具正在对二进制数据进行编码并且不喜欢 0x8B,很可能是因为它 >=0x80。如果您进一步阅读您的 JSON,其中有许多\ufffd-s,所有高于(或等于)0x80 的值都已替换为此。因此,即使 JSON 支持内部的原始二进制数据(但它不支持),此时的数据也会被不可恢复地破坏。

于 2017-12-18T22:52:48.380 回答
0

在 Java 中,您可以使用 GZIPInputStream 类来解码 GZIP 数据,我认为您需要先将值转换为 ByteArrayInputStream。

于 2017-12-18T20:27:49.320 回答