解压 Gzip JSON 响应时出现错误:StreamCorruptedException: 无效的流标头:7B227061

huangapple go评论75阅读模式
英文:

Decompressing Gzip JSON Response : StreamCorruptedException: invalid stream header: 7B227061

问题

基本上,我试图通过解压缩gzip来将gzip编码的JSON响应转换为Java中的POJO对象。首先,我从API调用中以字节数组形式获取响应。

CategoriesFullDetails categoriesFullDetails = new CategoriesFullDetails();
UriComponents getAllCategoriesUri = UriComponentsBuilder
        .fromHttpUrl(baseUrl + MENU_CATEGORY_FULL)
        .buildAndExpand(businessId);
String getAllCategoriesUrl = getAllCategoriesUri.toUriString();
HttpHeaders requestHeaders = new HttpHeaders();

requestHeaders.set("Content-Type", "application/json");
requestHeaders.set("Accept-Encoding", "gzip");

HttpEntity httpEntity = new HttpEntity(requestHeaders);
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
client.setRequestFactory(requestFactory);
client.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
byte[] responseBytes = client
        .exchange(getAllCategoriesUrl, HttpMethod.GET, httpEntity, byte[].class).getBody();

当我将上述gzip响应转换并存储为字节数组后,我希望将其解压缩并添加到我的POJO类CategoriesFullDetails中。

下面是调用将对字节数组进行解压缩的方法:

try {
    categoriesFullDetails = decompress(responseBytes);
    return categoriesFullDetails;
} catch (ClassNotFoundException | IOException e) {
    e.printStackTrace();
    return  null;
}

public CategoriesFullDetails decompress(byte[] data) throws IOException, ClassNotFoundException {
    ByteArrayInputStream in = new ByteArrayInputStream(data);
    GZIPInputStream gis = new GZIPInputStream(in);
    ObjectInputStream is = new ObjectInputStream(gis);
    return (CategoriesFullDetails) is.readObject();
}

在调试这个解压缩方法时,我发现它成功地将数据转换为ByteArrayInputStream,然后转换为GZIPInputStream(方法的前两行正常工作)。但是,问题出现在ObjectInputStream is = new ObjectInputStream(gis);这一行,报错信息为StreamCorruptedException: invalid stream header: 7B227061

我希望有人能帮助我解决这个问题,我已经花了3天,但仍然无法解决。

英文:

So basically im trying to get a gzip encoded json response to a pojo in java by trying to decompress the gzip. At first im getting the response in byte array form from the api call.

CategoriesFullDetails categoriesFullDetails = new CategoriesFullDetails();
        UriComponents getAllCategoriesUri = UriComponentsBuilder
                .fromHttpUrl(baseUrl + MENU_CATEGORY_FULL)
                .buildAndExpand(businessId);
        String getAllCategoriesUrl = getAllCategoriesUri.toUriString();
        HttpHeaders requestHeaders = new HttpHeaders();

        requestHeaders.set("Content-Type", "application/json");
        requestHeaders.set("Accept-Encoding", "gzip");

        HttpEntity httpEntity = new HttpEntity(requestHeaders);
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        client.setRequestFactory(requestFactory);
        client.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        byte[] responseBytes = client
                .exchange(getAllCategoriesUrl, HttpMethod.GET, httpEntity, byte[].class).getBody();

Once i get the gzip response converted and stored as a byte array as shown above, i want to decompress it and add it to a pojo of mine which is CategoriesFullDetails.

Below im calling the method which is going to decompress the byte array.

            try {
                categoriesFullDetails = decompress(responseBytes);
                return categoriesFullDetails;
            } catch (ClassNotFoundException | IOException e) {
                e.printStackTrace();
                return  null;
            }

    public CategoriesFullDetails decompress(byte[] data) throws IOException, ClassNotFoundException {
        ByteArrayInputStream in = new ByteArrayInputStream(data);
        GZIPInputStream gis = new GZIPInputStream(in);
        ObjectInputStream is = new ObjectInputStream(gis);
        return (CategoriesFullDetails) is.readObject();
    }

So what i found out when debugging this decompress method was, it converts the data to a ByteArrayInputStream and then to a GZIPInputStream successfully (first 2 lines of the method works fine). But then error is thrown at ObjectInputStream is = new ObjectInputStream(gis);
saying StreamCorruptedException: invalid stream header: 7B227061

I hope someone can help me and fix this, its been 3 days and still i cant solve it.

答案1

得分: 1

7B227061 是这个 ASCII 的十六进制表示:

{"pa

也就是说,它看起来像是 JSON 数据的前4个字节。问题是,你有一个经过gzip压缩的JSON文本流,而你正在将它传递给一个ObjectInputStream,而该流通常用于读取序列化的Java对象数据。

只需将GzipObjectStream传递给你的JSON解析器。或者,如果你更愿意,可以将整个输入流读取为一个字符串,然后将该字符串传递给解析器。

例如,如果你正在使用Jackson库,那么可以这样做:

ObjectMapper mapper = new ObjectMapper();
CategoriesFullDetails jsonMap = mapper.readValue(gis, CategoriesFullDetails.class);
英文:

7B227061 is the hex equivalent of this ASCII:

{"pa

I.e. it looks like the first 4 bytes of JSON data. The issue is that you have a gzipped stream of JSON text and you're passing it to an ObjectInputStream, which is for reading serialised Java object data.

Just pass the GzipObjectStream to your JSON parser. Or, read the entire input stream into a string, if you prefer, and then pass the string to your parser.

E.g., if you're using Jackson, then:

ObjectMapper mapper = new ObjectMapper();
CategoriesFullDetails jsonMap = mapper.readValue(gis, CategoriesFullDetails.class);

huangapple
  • 本文由 发表于 2020年10月17日 15:10:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/64399903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定