Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GZIP compression with Spring Boot/MVC/JavaConfig with RESTful

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 Spring MVC infrastructure (filters/etc) and have it automatically do the JSON conversion and compression (i.e. 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?

We don't currently have any XML based configuration.

like image 309
user3182614 Avatar asked Jan 28 '14 15:01

user3182614


2 Answers

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

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: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#how-to-enable-http-response-compression

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

like image 55
John Culviner Avatar answered Oct 14 '22 01:10

John Culviner


On recents versions in application.yml config:

---  spring:   profiles: dev  server:   compression:     enabled: true     mime-types: text/html,text/css,application/javascript,application/json  --- 
like image 28
M. Reza Nasirloo Avatar answered Oct 13 '22 23:10

M. Reza Nasirloo