Usecase:
This blogpost talks about using GZip compression on a REST service through the use of JAXRS 2.0 interceptors. The usecase below uses Jersey 2.x. Details on interceptors and filters can be found here.
Pre-requisites:
JDeveloper 12.1.3.0.0
Steps:
Use a working REST service that you already have and want to use GZip compression on. Alternately, create a REST service from scratch using the steps mentioned in my previous blogpost. However, ensure that you are using Jersey 2.0 libraries.
Use a working REST service that you already have and want to use GZip compression on. Alternately, create a REST service from scratch using the steps mentioned in my previous blogpost. However, ensure that you are using Jersey 2.0 libraries.
Next, create a new java class that implements ‘WriterInterceptor’. Write the below code in it. Notice that we have an annotation @ Provider at the class level.
We are also checking if the client accepts encoding of 'gzip' format, and only then performing the gzip compression.
package project1;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
@Provider
public class GZIPWriterInterceptor implements WriterInterceptor {
public GZIPWriterInterceptor() {
super();
}
private HttpHeaders context;
public GZIPWriterInterceptor(@Context HttpHeaders context) {
this.context = context;
}
@Override
public void aroundWriteTo(WriterInterceptorContext writerInterceptorContext) throws IOException,WebApplicationException {
// TODO Implement this method
String acceptEncoding = context.getHeaderString("Accept-Encoding");
if (acceptEncoding != null && acceptEncoding.contains("gzip")) {
final OutputStream outputStream = writerInterceptorContext.getOutputStream();
writerInterceptorContext.setOutputStream(new GZIPOutputStream(outputStream));
writerInterceptorContext.getHeaders().putSingle("Content-Encoding", "gzip");
}
writerInterceptorContext.proceed();
}
}
Next, add the header 'Accept-Encoding' to the request and send again. This time, gzip compression takes place. Notice that the size of data has now reduced to 123 from 155.
Find my sample application here.
Side note: The sample application also uses the concept of name binding by creating a custom annotation @Compressor and attaching it to the GZipWriterInterceptor class. Additionally, the annotation is specified on the methods for which GZip compression is required. This is not required, but comes in handy if you want to apply compression on some methods, and leave out the rest uncompressed.
Do check my next post which talks about decoding the gzip encoded data in a java client.