Java 从 json 属性解压缩 HTTP GZIP 内容



我们正在使用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": "u001fufffdu0008u0000u0000u0000u0000u0000u0000u0003ufffd]kufffdu0014DZufffd/ufffdYIufffd#ufffd*ufffdoufffdufffdufffdu0002tu0010^ufffdu001cu000eE=ufffd{ufffdbufffdufffdEufffdufffdCufffdufffdfufffd,ufffdu003eufffdufffdufffdu001efu001au0008u0005ufffdufffdgufffdufffdufffdYYUufffdufffd;ufffdoNufffdufffdufffdgufffdu0011UdKufffdu0015u0015ufffdou000eHufffdu000cu0015IqndCufffdufffdufffdufffdufffdufffdufffd ... "
}

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

您的数据已不可恢复地损坏。通常,我建议使用 Base64 编码将打包的二进制数据传输到 JSON 中,但您可以在 JSON 字符串中的二进制数据中阅读可能的替代方案。如果你喜欢实验,比 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>

除了 String-thing(这通常不是一个好主意)之外,这就是你解压缩 gzip 压缩字节数组的方式。
然而,有效的gzip数据以一个神奇的数字0x1F,0x8B开头(参见维基百科,或者你也可以挖掘实际的规范)。您的数据以0x1F(u001F部分)开头,但以 Unicodeufffd字符开头,该字符是替换字符(再次参见维基百科)。
一些工具正在编码二进制数据并且不喜欢0x8B,很可能是因为它是>=0x80。如果你进一步阅读你的 JSON,里面有很多ufffd-s,所有高于(或等于)0x80的值都已替换为 this。因此,即使JSON内部支持原始二进制数据(但事实并非如此),目前的数据也无法恢复。

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

最新更新