当前位置: 首页 > 面试题库 >

包裹身体订阅者 在GZIPInputStream中导致挂起

朱硕
2023-03-14
问题内容

我正在使用新java.net.http类来处理异步HTTP请求和响应交换,并且我试图找到一种方法使BodySubscriber处理不同的编码类型,例如gzip。

但是,映射a BodySubsriber<InputStream>以便基础流被a包裹GZIPInputStream(当在响应标头中找到“
Content-Encoding:gzip”时)会导致挂起。没有例外,只是完全停止活动。

映射BodySubscriber外观的代码如下所示:

private HttpResponse.BodySubscriber<InputStream> gzippedBodySubscriber(
        HttpResponse.ResponseInfo responseInfo) {
    return HttpResponse.BodySubscribers.mapping(
            HttpResponse.BodySubscribers.ofInputStream(),
            this::decodeGzipStream);
}

private InputStream decodeGzipStream(InputStream gzippedStream) {
    System.out.println("Entered decodeGzipStream method.");
    try {
        InputStream decodedStream = new GZIPInputStream(gzippedStream);
        System.out.println(
                "Created GZIPInputStream to handle response body stream.");
        return decodedStream;
    } catch (IOException ex) {
        System.out.println("IOException occurred while trying to create GZIPInputStream.");
        throw new UncheckedIOException(ex);
    }
}

接收到具有“ gzip”编码的HTTP响应,控制台将显示以下内容:

输入了EncodedBodyHandler.apply方法。
输入了encodeGzipStream方法。

什么也看不到,因此GZIPInputStream永远不会执行构造函数调用之后的行。

有谁知道为什么这种尝试将InputStreama
BodySubscriber<InputStream>中的包裹GZIPInputStream挂起?

注意:未编码(原始文本)HTTP响应正文的等效方法仅包含对的调用,BodySubscribers.ofInputStream()而没有任何映射,这使得可以毫无问题地接收和显示响应。


问题答案:

这确实是一个错误。我已经记录了JDK-8217264。我可以建议两个解决方法:

解决方法一

不要使用BodySubscribers.mapping-而是在获取HttpResponse的主体后将其InputStream转换为GZIPInputStream

GZIPInputStream gzin = new GZIPInputStream(resp.getBody());

解决方法二

让映射函数返回a Supplier<InputStream>,注意不要创建GZIPInputStream直到Supplier::get被调用

static final class ISS implements Supplier<InputStream> {
    final InputStream in;
    GZIPInputStream gz;
    ISS(InputStream in) {
        this.in = in;
    }
    public synchronized InputStream get() {
        if (gz == null) {
            try {
                gz = new GZIPInputStream(in);
            } catch (IOException t) {
                throw new UncheckedIOException(t);
            }
        }
        return gz;
    }
}


 类似资料:
  • 我试图用JAXB从XSD生成java类。 XSD是我公司的官方XSD,因此我不能仅为我的项目修改它们。在害怕在这个网站上尝试和搜索之后,我决定直接问这个问题。 我有这个在我的XSD: 这导致了一个问题:包装。指数行已在包中定义。指数 在查看生成的代码后,我可以看到,我们有一个静态的类行,进入另一个静态的内部类行(在另一个索引下) 我得到错误的行(在顶部底部)嵌套的类型行不能隐藏封闭类型 如果名称发

  • 我通读了RxJS文档,并希望确保我理解了< code > subscriber . unsubscribe()和< code > subscriber . complete()之间的区别。 假设我有一个有两个订阅者的可观察对象,订阅者1和订阅者2。如果订阅者1对其订阅调用取消订阅,它将不再接收来自可观察对象的通知,但订阅者2将继续接收它们。 <代码>的文档。complete(): 观察者回调,用于

  • 我试图在Java中使用GZIPInputStream来解压缩来自我的。NET应用程序(它以GZIP格式压缩)的图像数据。图像数据以Base64字符串传输,因为它是作为XML文本同步的。我假设流会读取到传入. read()参数的缓冲区中,直到缓冲区饱和。它没有像我预期的那样工作,也就是说,. read()每次读取操作只能读取800字节左右。这对于小图像不是问题,但对于大图像,如800 KB,解压缩需

  • 在我的帐户页面/视图订阅中,在操作段落中,我有一个取消按钮,但没有挂起按钮。你知道这是否正常吗? 我跟踪了这个函数,它只返回取消数据:wcs_get_all_user_actions_for_subscription 谢谢你的帮助

  • 我们接近完成一个完整的 Flux 闭环了,现在只差一个至关重要的环节: _________ _________ ___________ | | | Change | | React | | Store |----▶ events |----▶ Views | |_________| |_________|

  • 订阅号的订阅者支持按照组织机构或单人进行添加,同时可以设置使用范围和订阅权限。 设置订阅组织机构:勾选组织机构节点后,所有自组织机构及成员都将订阅此订阅号 新增/删除订阅者:点击新增订阅者/删除订阅者-选择相应人员