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.
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+
# 🗜️🗜️🗜️
server.compression.enabled=true
# opt in to content types
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
# not worth the CPU cycles at some point, probably
server.compression.min-response-size=10240
In 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
Older than 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");
}
}
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
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...)