Использование сжатия GZIP с Spring Boot/MVC/JavaConfig с RESTful
Мы используем Spring Boot/MVC с java-config на основе аннотаций для серии RESTful
услуги, и мы хотим, чтобы выборочно включить HTTP GZIP
сжатие потока на некоторых ответах API.
Я знаю, что могу сделать это вручную в моем контроллере и byte[] @ResponseBody
Однако мы бы предпочли полагаться на инфраструктуру SpringMVC (фильтры / и т. д.), чтобы она автоматически выполняла преобразование и сжатие JSON (т. е. метод возвращает POJO).
Как я могу включить сжатие GZIP в ResponseBody или встроенном экземпляре Tomcat, и таким образом мы можем выборочно сжимать только некоторые ответы?
Спасибо!
PS: В настоящее время у нас нет конфигурации на основе XML.
8 ответов
Остальные ответы устарели и / или слишком сложны для чего-то, что должно быть простым IMO (как долго gzip существует сейчас? Дольше, чем Java...) Из документации:
В приложении. Свойства 1.3+
server.compression.enabled=true
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
В заявке. Свойства 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
Производственное примечание IRL:
Также, чтобы избежать всего этого, рассмотрите возможность использования настройки прокси / балансировщика нагрузки перед Tomcat с nginx и / или haproxy или аналогичной, так как он будет обрабатывать статические ресурсы и намного эффективнее и проще gzip, чем модель потоков Java/Tomcat.
Вы не хотите бросать "кошку в ванну", потому что она занята сжатием вещей вместо того, чтобы обслуживать запросы (или, более вероятно, раскручивает потоки / ест процессор / кучу, бездельничая, ожидая ввода-вывода базы данных при выполнении счета AWS, который почему традиционный Java/Tomcat может не быть хорошей идеей для начала, в зависимости от того, что вы делаете, но я отвлекся...)
ссылки: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
На последних версиях в application.yml
конфигурации:
---
spring:
profiles: dev
server:
compression:
enabled: true
mime-types: text/html,text/css,application/javascript,application/json
---
По сути, это то же решение, что и @ 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);
}
}
);
}
};
}
Я добавил для этого:
Сжатие сервера
server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
взяты из http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/
Spring Boot 1.4 Используйте это для Javascript HTML Json для всех сжатий.
server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript
Enabeling GZip в Tomcat не работает в моем проекте Spring Boot. Я использовал CompressingFilter, найденный здесь.
@Bean
public Filter compressingFilter() {
CompressingFilter compressingFilter = new CompressingFilter();
return compressingFilter;
}
Чтобы включить сжатие GZIP, вам нужно изменить конфигурацию встроенного экземпляра Tomcat. Для этого вы объявляете EmbeddedServletContainerCustomizer
боб в вашей конфигурации 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 content-encoding.
У меня была такая же проблема в моем проекте Spring Boot+Spring Data при вызове @RepositoryRestResource
,
Проблема в возвращаемом типе MIME; который application/hal+json
, Добавление его в server.compression.mime-types
собственность решила эту проблему для меня.
Надеюсь, это поможет кому-то еще!