4

There are some filters out there but there are no working Java only solutions or some useful libraries. I am using Spring MVC with Tomcat and deploy release to Heroku (so cannot change servlet container configuration). How to enable REST gzip compression in Spring MVC without XML?

tereško
  • 58,060
  • 25
  • 98
  • 150

2 Answers2

4

You could set the rule for using compression on your servlet container, for example apache-tomcat you could use the compression property. From documentation:

compression

The Connector may use HTTP/1.1 GZIP compression in an attempt to save server bandwidth. The acceptable values for the parameter is "off" (disable compression), "on" (allow compression, which causes text data to be compressed), "force" (forces compression in all cases), or a numerical integer value (which is equivalent to "on", but specifies the minimum amount of data before the output is compressed). If the content-length is not known and compression is set to "on" or more aggressive, the output will also be compressed. If not specified, this attribute is set to "off".

Note: There is a tradeoff between using compression (saving your bandwidth) and using the sendfile feature (saving your CPU cycles). If the connector supports the sendfile feature, e.g. the NIO connector, using sendfile will take precedence over compression. The symptoms will be that static files greater that 48 Kb will be sent uncompressed. You can turn off sendfile by setting useSendfile attribute of the connector, as documented below, or change the sendfile usage threshold in the configuration of the DefaultServlet in the default conf/web.xml or in the web.xml of your web application.

compressionMinSize

If compression is set to "on" then this attribute may be used to specify the minimum amount of data before the output is compressed. If not specified, this attribute is defaults to "2048".

Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
1

One option is to change to Spring Boot and use an embedded Tomcat. Then you can use the ConfigurableEmbeddedServletContainer as suggested by Andy Wilkinson and myself in the answers to this question:

@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);
                        }
                    }
            );
        }
    };
}

If you choose to switch to Spring Boot, there is a specific chapter about Heroku deployment in the Spring Boot reference docs.

Community
  • 1
  • 1
matsev
  • 32,104
  • 16
  • 121
  • 156