繁体   English   中英

在GZIPInputStream中包装BodySubscriber <InputStream>会导致挂起

[英]Wrapping BodySubscriber<InputStream> in GZIPInputStream leads to hang

我正在使用新的java.net.http类来处理异步HTTP请求+响应交换,我正在尝试找到让BodySubscriber处理不同编码类型(如gzip)的方法。

但是,映射BodySubsriber<InputStream>以便底层流由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方法。
输入decodeGzipStream方法。

没有看到更多,所以从不执行调用GZIPInputStream构造函数之后的行。

有谁知道为什么从GZIPInputStreamBodySubscriber<InputStream>包装InputStream尝试是挂起的?

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

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

解决方法之一

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

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

解决方法二

让映射函数返回一个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;
    }
}

遇到了完全相同的问题。 我在BodySubscribers.mapping方法的Javadoc中尝试了这个例子。 相同的行为,应用程序挂起没有任何错误。

可能是一个错误,因为这是Javadoc的官方示例。

  public static <W> BodySubscriber<W> asJSON(Class<W> targetType) {
     BodySubscriber<InputStream> upstream = BodySubscribers.ofInputStream();

     BodySubscriber<W> downstream = BodySubscribers.mapping(
           upstream,
           (InputStream is) -> {
               try (InputStream stream = is) {
                   ObjectMapper objectMapper = new ObjectMapper();
                   return objectMapper.readValue(stream, targetType);
               } catch (IOException e) {
                   throw new UncheckedIOException(e);
               }
           });
    return downstream;
 } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM