We use Spring Boot/MVC with annotation-based java-config for series of RESTful
services and we want to selectively enable HTTP GZIP
stream compression on some API responses.
I know I can do this manually in my controller and a byte[] @ResponseBody
, however we'd prefer to rely on the SpringMVC infrastructure (filters/etc) and have it automatically do the JSON conversion and compression (ie the method returns a POJO).
How can I enable GZIP compression in the ResponseBody or embedded Tomcat instance, and in a way we can selectively compress only some responses?
Thanks!
PS.: We don't currently have any XML based configuration.
On recents versions in
application.yml
config:To enable GZIP compression, you need to modify the configuration of the embedded Tomcat instance. To do so, you declare a
EmbeddedServletContainerCustomizer
bean in your Java configuration and then register aTomcatConnectorCustomizer
with it.For example:
See the Tomcat documentation for more details on the various compression configuration options that are available.
You say that you want to selectively enable compression. Depending on your selection criteria, then the above approach may be sufficient. It enables you to control compression by the request's user-agent, the response's size, and the response's mime type.
If this doesn't meet your needs then I believe you will have to perform the compression in your controller and return a byte[] response with a gzip content-encoding header.
I had the same problem into my Spring Boot+Spring Data project when invoking to a
@RepositoryRestResource
.The problem is the MIME type returned; which is
application/hal+json
. Adding it to theserver.compression.mime-types
property solved this problem for me.Hope this helps to someone else!
The rest of these answers are out of date and/or over the top complicated for something that should be simple IMO (how long has gzip been around for now? longer than Java...) From the docs:
In application.properties 1.3+
In application.properties 1.2.2 - <1.3
Older than 1.2.2:
Also note this will ONLY work if you are running embedded tomcat:
If you plan to deploy to a non embedded tomcat you will have to enable it in server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation
IRL Production Note:
Also to avoid all of this consider using a proxy/load balancer setup in front of Tomcat with nginx and/or haproxy or similar since it will handle static assets and gzip MUCH more efficiently and easily than Java/Tomcat's threading model.
You don't want to throw 'cat in the bath because it's busy compressing stuff instead of serving up requests (or more likely spinning up threads/eating CPU/heap sitting around waiting for database IO to occur while running up your AWS bill which is why traditional Java/Tomcat might not be a good idea to begin with depending on what you are doing but I digress...)
refs: 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
Enabeling GZip in Tomcat doesn't worked in my Spring Boot Project. I used CompressingFilter found here.
I have added for this:
Server compression
taken from http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/