Использование сжатия 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.
Ответы
Ответ 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;
}
Ответ 6
Я добавил для этого:
Сжатие сервера
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/
Ответ 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
разрешило эту проблему для меня.
Надеюсь, это поможет кому-то еще!