使用Spring Boot / MVC / JavaConfig和RESTful进行GZIP压缩

我们使用Spring Boot / MVC和基于注解的java-config来实现一系列RESTful服务,并且我们希望在某些API响应上select性地启用HTTP GZIPstream压缩。

我知道我可以在我的控制器和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

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

这与@andy-wilkinson提供的解决scheme基本相同,但从Spring Boot 1.0开始, customize(…)方法具有ConfigurableEmbeddedServletContainer参数。

另外值得一提的是,Tomcat默认只压缩text/htmltext/xmltext/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.ymlconfiguration中的最近版本:

 --- 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属性为我解决了这个问题。

希望这有助于别人!