Рубрики
Без рубрики

Как сжать запросы С помощью пружинной RestTemplate

Узнайте, как создать перехватчик для RestTemplate, который сжимает содержимое запроса.

Автор оригинала: baeldung.

1. введение

В этом коротком руководстве мы рассмотрим, как отправлять HTTP-запросы, содержащие сжатые данные.

Кроме того, мы рассмотрим, как настроить веб-приложение Spring таким образом, чтобы оно обрабатывало сжатые запросы.

2. Отправка Сжатых Запросов

Во-первых, давайте создадим метод, который сжимает массив байтов. Это скоро пригодится:

public static byte[] compress(byte[] body) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
        gzipOutputStream.write(body);
    }
    return baos.toByteArray();
}

Далее, нам нужно реализовать ClientHttpRequestInterceptor для изменения запроса. Обратите внимание, что мы оба отправим соответствующие заголовки сжатия HTTP, а также вызовем наш метод сжатия тела:

public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec)
  throws IOException {
    HttpHeaders httpHeaders = req.getHeaders();
    httpHeaders.add(HttpHeaders.CONTENT_ENCODING, "gzip");
    httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
    return exec.execute(req, compress(body));
}

Наш перехватчик принимает тело исходящего запроса и сжимает его в формате GZIP. В этом примере мы используем стандарт Java GZIPOutputStream для выполнения работы за нас.

Кроме того, мы должны добавить соответствующие заголовки для кодирования данных. Это позволяет конечной точке назначения знать, что она имеет дело с данными, сжатыми в формате GZIP.

Наконец, мы добавляем перехватчик в наше определение RestTemplate :

@Bean
public RestTemplate getRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
    return restTemplate;
}

3. Обработка Сжатых Запросов

По умолчанию большинство веб-серверов не понимают запросы, содержащие сжатые данные. Весенние веб-приложения ничем не отличаются. Поэтому нам нужно настроить их для обработки таких запросов.

В настоящее время только веб-серверы Jetty и Undertow обрабатывают тела запросов с данными в формате GZIP. Пожалуйста, ознакомьтесь с нашей статьей о конфигурации приложения Spring Boot для настройки веб-сервера Jetty или Undertow.

3.1. Веб-сервер Причала

В этом примере мы настраиваем веб-сервер Jetty, добавляя Jetty GzipHandler . Этот обработчик пристани создан для сжатия ответов и распаковки запросов.

Однако добавить его на веб-сервер Jetty недостаточно. Нам нужно установить размер буфера inflate на значение, большее нуля, чтобы включить декомпрессию:

@Bean
public JettyServletWebServerFactory jettyServletWebServerFactory() {
    JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
    factory.addServerCustomizers(server -> {
        GzipHandler gzipHandler = new GzipHandler();
        gzipHandler.setInflateBufferSize(1);
        gzipHandler.setHandler(server.getHandler());

        HandlerCollection handlerCollection = new HandlerCollection(gzipHandler);
        server.setHandler(handlerCollection);
    });
    return factory;
}

3.2. Веб-сервер Undertow

Аналогичным образом, мы можем настроить веб-сервер Undertow для автоматической распаковки запросов для нас. В этом случае нам нужно добавить пользовательский Обработчик кодировки запроса .

Мы настраиваем обработчик кодирования для обработки исходных данных GZIP из запроса:

@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory() {
    UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
    factory.addDeploymentInfoCustomizers((deploymentInfo) -> {
        deploymentInfo.addInitialHandlerChainWrapper(handler -> new RequestEncodingHandler(handler)
          .addEncoding("gzip", GzipStreamSourceConduit.WRAPPER));
    });
    return factory;
}

4. Заключение

И это все, что нам нужно сделать, чтобы сжатые запросы работали!

В этом уроке мы рассмотрели, как создать перехватчик для RestTemplate , который сжимает содержимое запроса. Кроме того, мы рассмотрели, как автоматически распаковывать эти запросы в наших веб-приложениях Spring.

Важно отметить, что мы должны отправлять сжатый контент только на веб-серверы, способные обрабатывать такие запросы .

Полный рабочий пример для веб-сервера Jetty приведен в разделе на GitHub .