使用Spring Boot / MVC / JavaConfig和RESTful进行GZIP压缩
我们使用Spring Boot / MVC和基于注解的java-config来实现一系列RESTful
服务,并且我们希望在某些API响应上select性地启用HTTP GZIP
stream压缩。
我知道我可以在我的控制器和byte[] @ResponseBody
手动执行此操作,但是我们更愿意依靠SpringMVC基础结构(filter/ etc),并自动执行JSON转换和压缩(即方法返回一个POJO)。
如何在ResponseBody或embedded式Tomcat实例中启用GZIP压缩,并以某种方式select性压缩一些响应?
谢谢!
PS .:我们目前没有任何基于XML的configuration。
其余的答案已经过时,并且/或者在顶端复杂的东西,应该是简单的国际海事组织(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.properties 1.2.2 – <1.3
server.tomcat.compression: on server.tomcat.compressableMimeTypes=application/json,application/xml,text/html,text/xml,text/plain
比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"); } }
另外请注意,如果你正在运行embedded式tomcat,这将只会工作:
如果你打算部署到一个非embedded式的tomcat,你将不得不启用它server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation
IRL生产注意事项:
同样为了避免所有这些,考虑在Tomcat之前使用nginx和/或haproxy或类似的代理/负载均衡器设置,因为它将比Java / Tomcat的线程模型更有效和更容易地处理静态资产和gzip。 你不想把“猫”扔在浴缸里,因为它忙于压缩东西,而不是提供请求(或者更可能是旋转线程/吃CPU,等待数据库IO在运行AWS账单时出现,这就是为什么Java可能不是一个好主意,首先取决于你在做什么,但我离题…)
参考: http : //docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#how-to-enable-http-response-compression
这与@andy-wilkinson提供的解决scheme基本相同,但从Spring Boot 1.0开始, customize(…)方法具有ConfigurableEmbeddedServletContainer参数。
另外值得一提的是,Tomcat默认只压缩text/html
, text/xml
和text/plain
的内容types。 下面是一个支持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); } } ); } }; }
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
在application.yml
configuration中的最近版本:
--- spring: profiles: dev server: compression: enabled: true mime-types: text/html,text/css,application/javascript,application/json ---
要启用GZIP压缩,您需要修改embedded式Tomcat实例的configuration。 为此,您需要在Javaconfiguration中声明EmbeddedServletContainerCustomizer
bean,然后使用它注册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); } }); } }; }
有关可用的各种压缩configuration选项的更多详细信息,请参阅Tomcat文档 。
你说你想select性地启用压缩。 根据您的select标准,上述方法可能就足够了。 它使您能够通过请求的用户代理,响应的大小和响应的MIMEtypes来控制压缩。
如果这不符合你的需要,那么我相信你将不得不在你的控制器中执行压缩,并返回一个带有gzip内容编docker的byte []响应。
在Tomcat中激活GZip并不适用于我的Spring Boot项目。 我用CompressingFilter在这里find。
@Bean public Filter compressingFilter() { CompressingFilter compressingFilter = new CompressingFilter(); return compressingFilter; }
调用到@RepositoryRestResource
时,我的Spring Boot + Spring Data项目中遇到了同样的问题。
问题是返回的MIMEtypes; 这是application/hal+json
。 将它添加到server.compression.mime-types
属性为我解决了这个问题。
希望这有助于别人!