Java HTTP Client是否处理压缩

时间:2018-11-27 15:11:31

标签: java java-11 java-http-client

我试图在新的Java HTTP Client中找到有关压缩处理的任何内容,但均失败了。是否有内置配置可以处理例如gzipdeflate压缩?

我希望例如使用BodyHandler像这样的东西:

HttpResponse.BodyHandlers.ofGzipped(HttpResponse.BodyHandlers.ofString())

但是我没看到。我也没有在HttpClient中看到任何配置。我在找错地方了吗?还是故意将其实施并推迟以支持图书馆?

3 个答案:

答案 0 :(得分:2)

令我感到惊讶的是,新的java.net.http框架无法自动处理此问题,但是以下内容对我而言可以处理以InputStream接收且未压缩或压缩的HTTP响应gzip:

public static InputStream getDecodedInputStream(
        HttpResponse<InputStream> httpResponse) {
    String encoding = determineContentEncoding(httpResponse);
    try {
        switch (encoding) {
            case "":
                return httpResponse.body();
            case "gzip":
                return new GZIPInputStream(httpResponse.body());
            default:
                throw new UnsupportedOperationException(
                        "Unexpected Content-Encoding: " + encoding);
        }
    } catch (IOException ioe) {
        throw new UncheckedIOException(ioe);
    }
}

public static String determineContentEncoding(
        HttpResponse<?> httpResponse) {
    return httpResponse.headers().firstValue("Content-Encoding").orElse("");
}

请注意,我还没有添加对“放气”类型的支持(因为我目前不需要它,而且我对“放气”的了解越多,听起来就越混乱了)。但我相信您可以通过在上述开关块上添加检查并将httpResponse.body()包裹在InflaterInputStream中来轻松支持“放气”。

答案 1 :(得分:1)

否,默认情况下不处理gzip / deflate压缩。如果需要,您必须在应用程序代码中实现它-例如通过提供自定义的BodySubscriber来处理它。或者,您可能想看看那里的某些反应式流库是否提供了这样的功能,在这种情况下,您可能可以使用BodyHandlers.fromSubscriber​(Flow.Subscriber<? super List<ByteBuffer>> subscriber)或{{1}中的一个将其插入}方法。

答案 2 :(得分:1)

这个问题有点老了,但是我最近发布了一个可解决此问题的库。该库称为Methanol,可在Maven上使用。

您可以使用它来解码响应,如下所示:

HttpResponse<String> response = client.send(request, MoreBodyHandlers.decoding(BodyHandlers.ofString()));

您还可以使用所需的任何BodyHandlerMoreBodyHandlers::decoding使您的处理程序看起来好像从未压缩过响应!它负责Content-Encoding标头和所有标头。默认情况下支持Gzip和deflate,而brotli也有module

更好的是,您可以使用自定义HttpClient进行透明压缩(无需添加Accept-Encoding):

Methanol client = Methanol.newBuilder()
    .autoAcceptEncoding(true) // note that true is the default
    .build();
HttpRequest request = ...
HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); // response is compressed transparently