Java HTTP Client обрабатывает сжатие - PullRequest
0 голосов
/ 27 ноября 2018

Я пытался найти упоминание об обработке сжатия в новом Java HTTP Client, но не смог.Есть ли встроенная конфигурация для обработки, например, gzip или deflate сжатия?

Я бы ожидал иметь BodyHandler для, например, что-то вроде этого:

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

но я не вижу ничего.Я не вижу никакой конфигурации в HttpClient.Я смотрю не в том месте или это намеренно не реализовано и не отложено для поддержки библиотек?

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Я также был удивлен, что новая инфраструктура java.net.http не обрабатывает это автоматически, но следующее работает для меня, чтобы обрабатывать ответы HTTP, которые получены как InputStream и которые либо распакованы, либо сжаты с помощью 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("");
}

Обратите внимание, что я не добавил поддержку типа "deflate" (потому что в настоящее время он мне не нужен, и чем больше я читаю о "deflate", тем больше беспорядка это звучало).Но я полагаю, что вы можете легко поддержать «deflate», добавив проверку к вышеуказанному блоку переключателей и заключив httpResponse.body() в InflaterInputStream.

0 голосов
/ 29 ноября 2018

Нет, сжатие gzip / deflate по умолчанию не обрабатывается.Вы должны будете реализовать это в своем коде приложения, если вам это нужно - например, предоставив настроенный BodySubscriber для его обработки.В качестве альтернативы - вы можете посмотреть, предлагают ли некоторые из библиотек реактивных потоков такую ​​функцию, и в этом случае вы можете передать это, используя один из методов BodyHandlers.fromSubscriber​(Flow.Subscriber<? super List<ByteBuffer>> subscriber) или BodyHandlers.ofPublisher().

...