Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling gzipped requests in a Spring Boot REST application

I have a Spring Boot REST app (1.5.6.RELEASE). I would like gzip compression incoming and outgoing. As per this documentation https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html I have set

server.compression.enabled=true
server.compression.mime-types=...

But this seems to only apply to gzipping responses from my service (and this is what the doc says actually "# If response compression is enabled.").

My problem is that incoming gzipped requests are not being decompressed, resulting in JSON parsing errors.

Does anyone know how I can turn on request decompression in my Spring Boot app?

EDIT An example:

POM snippet:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Controller code:

@RestController
public class Controller {
    @RequestMapping(value = "/", method = RequestMethod.POST, consumes = "application/json")
    public String post(@RequestBody Map<String, String> request) {
        return request.get("key");
   }
}

Test using curl:

$ echo '{ "key":"hello" }' > body
$ curl -X POST -H "Content-Type: application/json" --data-binary @body http://localhost:8080 # prints 'hello'
$ echo '{ "key":"hello" }' | gzip > body.gz
$ curl -X POST -H "Content-Type: application/json" -H "Content-Encoding: gzip" --data-binary @body.gz http://localhost:8080 # fails

The gzipped call fails with message:

{"timestamp":1505843443456,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\\r, \\n, \\t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\\r, \\n, \\t) is allowed between tokens\n at [Source: java.io.PushbackInputStream@50ebec25; line: 1, column: 2]","path":"/"}
like image 623
B255 Avatar asked Sep 19 '17 11:09

B255


People also ask

How do I compress a REST API response?

The REST API compresses the response if the client properly specifies this header. The response includes the header Content-Encoding: gzip or Accept-Encoding: deflate . You can also compress any request by including a Content-Encoding: gzip or Content-Encoding: deflate header.

How do I know if API response is Gzipped?

You can tell using Developer Tools (F12). Go to the Network tab, select the file you want to examine and then look at the Headers tab on the right. If you are gzipped, then you will see that in the Content-Encoding.

What is HTTP response compression in spring boot?

Compression is an important way to increase the performance of web applications, especially for low bandwidth internet access. It helps to reduce the size of HTTP packages and deliver faster.

Does gzip improve performance?

Gzip is a fast and easy way to improve page speed performance while still delivering a high-quality experience to your users. See if your website supports gzip by running a free speed test, and sign up for a free trial for more insights into your website's performance.


1 Answers

The server.compression.* configuration keys are about HTTP response compression only. I'm not aware of any general solution, nor if servers support that natively.

You can support that by using a Servlet filter that does just that, but Spring Boot does not offer that feature.

like image 189
Brian Clozel Avatar answered Oct 12 '22 20:10

Brian Clozel