【问题标题】:Decompressing Gzip JSON Response : StreamCorruptedException: invalid stream header: 7B227061 [duplicate]解压缩 Gzip JSON 响应:StreamCorruptedException:无效流标头:7B227061 [重复]
【发布时间】:2020-10-17 07:10:49
【问题描述】:

所以基本上我试图通过尝试解压缩 gzip 来获得对 java 中的 pojo 的 gzip 编码的 json 响应。起初我从 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(该方法的前 2 行工作正常)。但随后在 ObjectInputStream is = new ObjectInputStream(gis); 处引发错误 说 StreamCorruptedException: invalid stream header: 7B227061

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

【问题讨论】:

  • 为什么要将GZIPInputStream 转换为ObjectInputStream?来自ObjectInputStream 类的javadocObjectInputStream 反序列化原始数据和先前使用ObjectOutputStream 编写的对象 我认为您只需解压缩GZIPInputStream。无需转换为ObjectInputStream
  • @Abra 你能告诉我如何解压缩 GZIPInputStream,这对我真的很有帮助,顺便说一句,如果我将它转换为 ObjectInputStream,那么我将能够将它添加到我的 pojo就像下一行一样。
  • 但如果它不是由ObjectOutputStream 制作的,你就不能这样做。

标签: java json spring spring-boot gzip


【解决方案1】:

7B227061 是此 ASCII 的十六进制等效项:

{"pa

即它看起来像 JSON 数据的前 4 个字节。问题是您有一个经过 gzip 压缩的 JSON 文本流,并且您将其传递给 ObjectInputStream,该对象用于读取序列化的 Java 对象数据。

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

例如,如果您使用的是 Jackson,那么:

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

【讨论】:

  • 嗨,问题是我还不能添加,因为在“ObjectInputStream is = new ObjectInputStream(gis);”处引发了错误,所以......在这种情况下如何?顺便说一句,我还尝试获取 api 对字符串的响应,但它不能那样工作,你的意思是我应该在“mapper.readValue(gis, CategoriesFullDetails.class) 中添加“gis”而不是“is” ); ",请帮帮我
  • 是的,我已经更正了我的答案。
  • 嘿伙计 thnx 很多伙计,它运作良好,我连续 3 天苦苦挣扎试图弄清楚这一点。对我来说意义重大,伙计,感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多