Использование сжатия GZIP с помощью Spring Boot / MVC / JavaConfig с RESTful
Мы используем Spring Boot / MVC с java-config на основе аннотаций для серии сервисов RESTful
и мы хотим выборочно включить сжатие streamа HTTP GZIP
в некоторых ответах API.
Я знаю, что могу сделать это вручную в моем controllerе и byte[] @ResponseBody
, однако мы предпочли бы полагаться на инфраструктуру SpringMVC (фильтры / etc) и автоматически выполнять преобразование и сжатие JSON (т. Е. Метод возвращает POJO).
Как включить GZIP-сжатие в ResponseBody или встроенном экземпляре Tomcat, и таким образом мы можем выборочно сжимать только некоторые ответы?
- Spring MVC @PathVariable получает усечение
- Что вызывает «java.lang.IllegalStateException: ни BindingResult, ни обычный целевой объект для bean name« command », ansible как атрибут запроса»?
- сеансы загрузки исключений из постоянного хранилища
- Ресурс API для облачных сообщений Firebase
- Мое приложение не может открыть ресурс ServletContext
Благодаря!
PS: В настоящее время мы не имеем никакой конфигурации на основе XML.
- Не удалось открыть ресурс ServletContext
- Доступ к областям профилированных объектов в streamах
- Разница между запросом MVC и компонентом MVC
- Как использовать атрибуты сеанса в Spring-mvc
- Spring настроить формат @ResponseBody JSON
- spring Exception при запуске приложения в WebSphere с java 8
- Spring HandlerInterceptor vs Servlet Filters
- Отправка сообщения конкретному пользователю в Spring Websocket
Остальные из этих ответов устарели и / или превышают сложность для чего-то, что должно быть простым ИМО (как долго на данный момент gzip существует дольше, чем Java …) Из документов:
В application.properties 1.3+
server.compression.enabled=true server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
В application.properties 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
Примечание:
Кроме того, чтобы избежать всего этого, используйте настройку балансировки прокси / нагрузки перед Tomcat с nginx и / или haproxy или аналогичными, поскольку она будет обрабатывать статические активы и gzip MUCH более эффективно и легко, чем модель streamовой передачи Java / Tomcat.
Вы не хотите бросать «кошку в ванну», потому что она занята сжатием материала вместо подачи запросов (или, более вероятно, разворачивает streamи / кушает процессор / кучу, сидя вокруг ожидания ввода-вывода базы данных при запуске вашего счета AWS, который почему традиционная Java / Tomcat не может быть хорошей идеей для начала, в зависимости от того, что вы делаете, но я отвлекаюсь …)
Это в основном то же самое решение, что и @ 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); } } ); } }; }
В версиях повторений в application.yml
config:
--- spring: profiles: dev server: compression: enabled: true mime-types: text/html,text/css,application/javascript,application/json ---
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
Чтобы включить сжатие 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 .
Вы говорите, что хотите выборочно включить сжатие. В зависимости от ваших критериев выбора, вышеуказанного подхода может быть достаточно. Он позволяет вам контролировать сжатие пользовательского агента запроса, размер ответа и тип mime ответа.
Если это не соответствует вашим потребностям, я полагаю, вам придется выполнить сжатие в вашем controllerе и вернуть ответ byte [] с заголовком кодирования содержимого gzip.
Enabeling GZip в Tomcat не работает в моем проекте Spring Boot. Я использовал CompressingFilter, найденный здесь .
@Bean public Filter compressingFilter() { CompressingFilter compressingFilter = new CompressingFilter(); return compressingFilter; }
Я добавил для этого:
Сжатие сервера
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 + Spring Data при вызове на @RepositoryRestResource
.
Проблема заключается в возврате типа MIME; который является application/hal+json
. Добавление этого свойства в свойство server.compression.mime-types
позволило решить эту проблему для меня.
Надеюсь, это поможет кому-то еще!