Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

HTTP Client Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Introduction

In this short tutorial, we'll look at how to send HTTP requests containing compressed data.

In addition, we'll look at how to configure a Spring web application so it handles compressed requests.

2. Sending Compressed Requests

Firstly, let's create a method that compresses a byte array. This will come in handy shortly:

public static byte[] compress(byte[] body) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
        gzipOutputStream.write(body);
    }
    return baos.toByteArray();
}

Next, we need to implement a ClientHttpRequestInterceptor to modify the request. Note that we'll both send the appropriate HTTP compression headers as well as call our body-compressing method:

public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec)
  throws IOException {
    HttpHeaders httpHeaders = req.getHeaders();
    httpHeaders.add(HttpHeaders.CONTENT_ENCODING, "gzip");
    httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
    return exec.execute(req, compress(body));
}

Our interceptor takes the outbound request body and compresses it using the GZIP format. In this example, we use Java's standard GZIPOutputStream to do the work for us.

In addition, we must add the appropriate headers for data encoding. This lets the destination endpoint know it is dealing with GZIP-compressed data.

Finally, we add the interceptor to our RestTemplate definition:

@Bean
public RestTemplate getRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
    return restTemplate;
}

3. Handling Compressed Requests

By default, most web servers do not understand requests containing compressed data. Spring web applications are no different. Therefore, we need to configure them to handle such requests.

Currently, only the Jetty and Undertow web servers handle request bodies with data in GZIP format. Please see our article on Spring Boot Application Configuration to set up a Jetty or Undertow web server.

3.1. Jetty Web Server

In this example, we customize a Jetty web server by adding a Jetty GzipHandler. This Jetty handler is built to compress responses and decompress requests.

However, adding it the Jetty web server is not enough. We need to set the inflateBufferSize to a value greater than zero to enable decompression:

@Bean
public JettyServletWebServerFactory jettyServletWebServerFactory() {
    JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
    factory.addServerCustomizers(server -> {
        GzipHandler gzipHandler = new GzipHandler();
        gzipHandler.setInflateBufferSize(1);
        gzipHandler.setHandler(server.getHandler());

        HandlerCollection handlerCollection = new HandlerCollection(gzipHandler);
        server.setHandler(handlerCollection);
    });
    return factory;
}

3.2. Undertow Web Server

Likewise, we can customize an Undertow web server to automatically decompress requests for us. In this case, we need to add a custom RequestEncodingHandler.

We configure the encoding handler to process GZIP source data from the request:

@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory() {
    UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
    factory.addDeploymentInfoCustomizers((deploymentInfo) -> {
        deploymentInfo.addInitialHandlerChainWrapper(handler -> new RequestEncodingHandler(handler)
          .addEncoding("gzip", GzipStreamSourceConduit.WRAPPER));
    });
    return factory;
}

4. Conclusion

And that's all we need to do to get compressed requests working!

In this tutorial, we covered how to create an interceptor for a RestTemplate that compresses the content of a request. Also, we looked at how to automatically decompress these requests in our Spring web applications.

It's important to note that we should only send compressed content to web servers capable of handling such requests.

A complete working example for the Jetty web server is over on GitHub.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
REST bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course :

>> CHECK OUT THE COURSE
HTTP Client bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
REST footer banner
Comments are closed on this article!