Подтвердить что ты не робот

Использование сжатия GZIP с помощью Spring Boot/MVC/JavaConfig с RESTful

Мы используем Spring Boot/MVC с java-config на основе аннотаций для серии сервисов RESTful, и мы хотим выборочно включить сжатие потока HTTP GZIP в некоторых ответах API.

Я знаю, что могу сделать это вручную в своем контроллере и byte[] @ResponseBody, однако мы предпочли бы полагаться на инфраструктуру SpringMVC (фильтры/etc) и автоматически выполнять преобразование и сжатие JSON (т.е. метод возвращает POJO).

Как включить GZIP-сжатие в ResponseBody или встроенном экземпляре Tomcat, и таким образом мы можем выборочно сжать только некоторые ответы?

Спасибо!

PS: В настоящее время мы не имеем никакой конфигурации на основе XML.

4b9b3361

Ответ 1

Остальные ответы на них устарели и/или слишком сложны для чего-то, что должно быть простым IMO (как долго gzip существует сейчас? Дольше, чем Java...) Из документации:

В заявке . Свойства 1. 3+

# 🗜️🗜️🗜️
server.compression.enabled=true
# opt in to content types
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
# not worth the CPU cycles at some point, probably
server.compression.min-response-size=10240 

В заявке. Свойства 1.2.2 - <1.3

server.tomcat.compression=on
server.tomcat.compressableMimeTypes=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css

Старше, чем 1.2.2:

@Component
public class TomcatCustomizer implements TomcatConnectorCustomizer {

  @Override
  public void customize(Connector connector) {
    connector.setProperty("compression", "on");
    // Add json and xml mime types, as they're not in the mimetype list by default
    connector.setProperty("compressableMimeType", "text/html,text/xml,text/plain,application/json,application/xml");
  }
}

Также обратите внимание, что это будет работать ТОЛЬКО, если вы используете встроенный tomcat:

Если вы планируете выполнить развертывание на не внедренном tomcat, вам необходимо включить его в server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation

Производственная записка IRL:

Также, чтобы избежать всего этого, рассмотрите возможность использования настройки прокси/балансировщика нагрузки перед Tomcat с nginx и/или haproxy или аналогичной, так как он будет обрабатывать статические ресурсы и намного эффективнее и проще gzip, чем модель потоков Java/Tomcat.

Вы не хотите бросать 'cat в ванну, потому что она занята сжатием вещей вместо того, чтобы обслуживать запросы (или, более вероятно, раскручивает потоки/поедает процессор/кучу, бездельничая, ожидая ввода-вывода базы данных при выполнении счета AWS, который почему традиционная Java/Tomcat может не быть хорошей идеей для начала, в зависимости от того, что вы делаете, но я отвлекся...)

ссылки: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#how-to-enable-http-response-compression

https://github.com/spring-projects/spring-boot/issues/2031

Ответ 2

Это в основном то же самое решение, что и @andy-wilkinson, но с Spring Boot 1.0 метод customize (...) имеет ConfigurableEmbeddedServletContainer.

Еще одна вещь, о которой стоит упомянуть, заключается в том, что Tomcat только сжимает типы контента text/html, text/xml и text/plain по умолчанию. Ниже приведен пример, который поддерживает сжатие application/json:

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer servletContainer) {
            ((TomcatEmbeddedServletContainerFactory) servletContainer).addConnectorCustomizers(
                    new TomcatConnectorCustomizer() {
                        @Override
                        public void customize(Connector connector) {
                            AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                            httpProtocol.setCompression("on");
                            httpProtocol.setCompressionMinSize(256);
                            String mimeTypes = httpProtocol.getCompressableMimeTypes();
                            String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE;
                            httpProtocol.setCompressableMimeTypes(mimeTypesWithJson);
                        }
                    }
            );
        }
    };
}

Ответ 3

В версиях повторений в application.yml config:

---

spring:
  profiles: dev

server:
  compression:
    enabled: true
    mime-types: text/html,text/css,application/javascript,application/json

---

Ответ 4

Spring Загрузка 1.4 Используйте это для JScript-кода HTML Json для всех сжатий.

server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript

Ответ 5

Enabeling GZip в Tomcat не работает в моем проекте Spring Boot. Я использовал CompressingFilter, найденный здесь.

@Bean
public Filter compressingFilter() {
    CompressingFilter compressingFilter = new CompressingFilter();
    return compressingFilter;
}

Ответ 7

Чтобы включить сжатие GZIP, вам необходимо изменить конфигурацию встроенного экземпляра Tomcat. Для этого вы объявляете EmbeddedServletContainerCustomizer bean в вашей конфигурации Java, а затем регистрируете с ней TomcatConnectorCustomizer.

Например:

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
            ((TomcatEmbeddedServletContainerFactory) factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                    httpProtocol.setCompression("on");
                    httpProtocol.setCompressionMinSize(64);
                }
            });
        }
    };
}

Дополнительную информацию о доступных параметрах конфигурации сжатия см. в документации Tomcat.

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

Если это не соответствует вашим потребностям, я полагаю, вам придется выполнить сжатие в вашем контроллере и вернуть ответ byte [] с заголовком кодировки содержимого gzip.

Ответ 8

У меня была такая же проблема в моем проекте Spring Boot + Spring Data при вызове на @RepositoryRestResource.

Проблема заключается в возврате типа MIME; которая равна application/hal+json. Добавление его в свойство server.compression.mime-types разрешило эту проблему для меня.

Надеюсь, это поможет кому-то еще!