Как включить сжатие gzip для кодирования контента с помощью клиента Jersey (JAX-RS 2.0)?

У меня есть приложение Java, в котором используется реализация JAX-RS 2.0 на Джерси, и я хочу включить сжатие gzip на стороне клиента. На сервере он включен, и я проверил это, посмотрев в Chrome «Размер / содержимое» в инструментах разработчика для определенного URL-адреса, который использует клиент.

Я вижу много информации и документации, циркулирующей в Интернете о настройке заголовков HTTP с фильтрами и декодировании тела ответа с помощью перехватчиков, и я не могу расшифровать, что мне на самом деле нужно для кодирования в клиенте.

У меня есть этот код:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    WebTarget targetBase = client.target(getBaseUrl());
    ...
}

Что я должен добавить, чтобы включить сжатие?


person Jason    schedule 19.03.2014    source источник


Ответы (4)


удалось сделать это с помощью:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    client.register(GZipEncoder.class);
    client.register(EncodingFilter.class);
    WebTarget targetBase = client.target(getBaseUrl());
    ...
}

Почти так же, как @Jason, но EncodingFilter обнаруживает для меня GzipEncoder.

person Jayen    schedule 20.08.2014
comment
Работал и для меня. - person Marcel; 15.05.2018

В моем примере (с JAX RS 2.x) и Джерси, где используется multipart, ничего из вышеперечисленного не сработало, но это сработало:

Client client = ClientBuilder.newBuilder()
            .register(EncodingFilter.class)
            .register(GZipEncoder.class)
            .property(ClientProperties.USE_ENCODING, "gzip")
            .register(MultiPartFeature.class)
            .register(LoggingFilter.class)
            .build();

По сути, то же самое, что и приведенные выше ответы, но пришлось добавить это свойство для «gzip».

person Khanna111    schedule 24.02.2016
comment
Я вижу, у вас нет строки gzip ACCEPT_ENCODING из принятого ответа. Вы пытались использовать это вместо USE_ENCODING gzip? - person Jason; 05.03.2016
comment
Акцент делается на запрос, а не на ответ - ACCEPT_ENCODING предназначен для того, чтобы сервер отвечал сжатым ответом, поскольку клиент может его принять. - person Khanna111; 07.03.2016
comment
Я понимаю разницу. Вы пробовали ACCEPT_ENCODING? Поскольку в вашем примере отсутствует это, я обеспокоен тем, что он отсутствовал, когда вы пробовали другие методы, упомянутые в этом вопросе. У меня есть эта проблема, потому что вы говорите, что по существу то же самое, что и в приведенных выше ответах, но мне пришлось добавить это свойство для gzip. Это означает, что вы только что добавили свойство для gzip... не изменили его и не удалили ACCEPT_ENCODING. Я просто хочу быть уверен, что ACCEPT_ENCODING не сработал для вас. - person Jason; 11.03.2016
comment
нет, у меня не получилось, чтобы запрос сжимался. - person Khanna111; 18.03.2016

Измените, чтобы выглядеть так:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    client.register(GZipEncoder.class);
    WebTarget targetBase = client.target(getBaseUrl());
    ...
    // new lines here:
    Invocation.Builder request = targetBase.request(MEDIA_TYPE);
    request.header(HttpHeaders.ACCEPT_ENCODING, "gzip");
    ...
}

В этом примере есть ссылки на некоторые поля и методы, которые я не включил в пример (например, MEDIA_TYPE), вам придется разобраться с ними самостоятельно. Должно быть довольно прямолинейно.

Я убедился, что это сработало, проанализировав заголовки ответов и отслеживая использование сети приложением. Я получил коэффициент сжатия 10: 1 в соответствии с проверками использования сети, которые я сделал. Это кажется правильным, ура!

person Jason    schedule 20.03.2014
comment
Добавлять заголовок Accept-Encoding вручную не нужно; регистрация GZipEncoder уже сделает это. - person ᴠɪɴᴄᴇɴᴛ; 26.05.2015
comment
@ Винсент для какой версии Джерси? Мой не делает этого без EncodingFilter. - person Jayen; 27.05.2015
comment
@Jayen Мой тоже, я не знал, что у меня тоже зарегистрирован EncodingFilter :| См. EncodingFilter JavaDoc. Вручную добавлять заголовок в любом случае не нужно. - person ᴠɪɴᴄᴇɴᴛ; 27.05.2015

Вместо того, чтобы регистрировать EncodingFilter и GZipEncoder по отдельности, вы можете использовать EncodingFeature напрямую. В Джерси 2.32 у меня были проблемы с незавершенными инъекциями и, как следствие, NullPointerExceptions.

Client client = ClientBuilder.newClient();
client.register(new EncodingFeature("gzip", GZipEncoder.class));
client.register(new HttpBasicAuthFilter(username, password));
WebTarget targetBase = client.target(getBaseUrl());

Обратите внимание на разницу между установкой параметра useEncoding

client.register(new EncodingFeature("gzip", GZipEncoder.class));

или не

client.register(new EncodingFeature(GZipEncoder.class));

если первоначальный запрос клиента уже закодирован gzip или если он просто указывает серверу, что он поймет сжатый ответ.

person Joe23    schedule 09.12.2020