Skip to content

Commit 7472127

Browse files
hugogiordanomaibin
authored andcommitted
BAEL-3188 How to compress requests using the Spring RestTemplate. (eugenp#7688)
* BAEL-3188 How to compress requests using the Spring RestTemplate. * BAEL-3188 How to compress requests using the Spring RestTemplate. Updated README. * BAEL-3188 How to compress requests using the Spring RestTemplate. * BAEL-3188 How to compress requests using the Spring RestTemplate. * BAEL-3188 How to compress requests using the Spring RestTemplate. Updated parent pom to add new module.
1 parent 06cbdfc commit 7472127

File tree

12 files changed

+384
-0
lines changed

12 files changed

+384
-0
lines changed

pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@
741741
<module>spring-remoting</module>
742742
<module>spring-rest</module>
743743
<module>spring-rest-angular</module>
744+
<module>spring-rest-compress</module>
744745
<module>spring-rest-full</module>
745746
<module>spring-rest-hal-browser</module>
746747
<module>spring-rest-query-language</module>
@@ -928,6 +929,7 @@
928929
<module>spring-remoting/remoting-rmi/remoting-rmi-server</module>
929930
<module>spring-rest</module>
930931
<module>spring-rest-angular</module>
932+
<module>spring-rest-compress</module>
931933
<module>spring-rest-full</module>
932934
<module>spring-rest-simple</module>
933935
<module>spring-resttemplate</module>
@@ -1433,6 +1435,7 @@
14331435
<module>spring-remoting</module>
14341436
<module>spring-rest</module>
14351437
<module>spring-rest-angular</module>
1438+
<module>spring-rest-compress</module>
14361439
<module>spring-rest-full</module>
14371440
<module>spring-rest-hal-browser</module>
14381441
<module>spring-rest-query-language</module>

spring-rest-compress/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=========================================================================
2+
## How to compress requests using the Spring RestTemplate Example Project
3+
4+
### Relevant Articles:
5+
- [How to compress requests using the Spring RestTemplate]()

spring-rest-compress/pom.xml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<artifactId>parent-boot-2</artifactId>
7+
<groupId>com.baeldung</groupId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<relativePath>../parent-boot-2</relativePath>
10+
</parent>
11+
<groupId>com.baeldung</groupId>
12+
<artifactId>spring-rest-compress</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<name>spring-rest-compress</name>
15+
16+
<properties>
17+
<java.version>1.8</java.version>
18+
<commons-io.version>2.6</commons-io.version>
19+
</properties>
20+
21+
<dependencies>
22+
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-web</artifactId>
26+
<exclusions>
27+
<exclusion>
28+
<groupId>org.springframework.boot</groupId>
29+
<artifactId>spring-boot-starter-tomcat</artifactId>
30+
</exclusion>
31+
</exclusions>
32+
</dependency>
33+
34+
<dependency>
35+
<groupId>org.springframework.boot</groupId>
36+
<artifactId>spring-boot-starter-jetty</artifactId>
37+
</dependency>
38+
39+
<dependency>
40+
<groupId>org.apache.httpcomponents</groupId>
41+
<artifactId>httpclient</artifactId>
42+
</dependency>
43+
44+
<dependency>
45+
<groupId>commons-io</groupId>
46+
<artifactId>commons-io</artifactId>
47+
<version>${commons-io.version}</version>
48+
</dependency>
49+
50+
<dependency>
51+
<groupId>org.springframework.boot</groupId>
52+
<artifactId>spring-boot-starter-test</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
</dependencies>
56+
57+
<build>
58+
<plugins>
59+
<plugin>
60+
<groupId>org.springframework.boot</groupId>
61+
<artifactId>spring-boot-maven-plugin</artifactId>
62+
</plugin>
63+
</plugins>
64+
</build>
65+
66+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.http.HttpHeaders;
6+
import org.springframework.http.HttpRequest;
7+
import org.springframework.http.client.ClientHttpRequestExecution;
8+
import org.springframework.http.client.ClientHttpRequestInterceptor;
9+
import org.springframework.http.client.ClientHttpResponse;
10+
11+
import java.io.IOException;
12+
13+
public class CompressingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
14+
15+
private static final Logger LOG = LoggerFactory.getLogger(CompressingClientHttpRequestInterceptor.class);
16+
17+
private static final String GZIP_ENCODING = "gzip";
18+
19+
/**
20+
* Compress a request body using Gzip and add Http headers.
21+
*
22+
* @param req
23+
* @param body
24+
* @param exec
25+
* @return
26+
* @throws IOException
27+
*/
28+
@Override
29+
public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec)
30+
throws IOException {
31+
LOG.info("Compressing request...");
32+
HttpHeaders httpHeaders = req.getHeaders();
33+
httpHeaders.add(HttpHeaders.CONTENT_ENCODING, GZIP_ENCODING);
34+
httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING);
35+
return exec.execute(req, GzipUtils.compress(body));
36+
}
37+
38+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.apache.commons.codec.Charsets;
4+
import org.apache.commons.io.IOUtils;
5+
6+
import java.io.ByteArrayInputStream;
7+
import java.io.ByteArrayOutputStream;
8+
import java.io.IOException;
9+
import java.util.zip.GZIPInputStream;
10+
import java.util.zip.GZIPOutputStream;
11+
12+
public class GzipUtils {
13+
14+
/**
15+
* Gzip a string.
16+
*
17+
* @param text
18+
* @return
19+
* @throws Exception
20+
*/
21+
public static byte[] compress(String text) throws Exception {
22+
return GzipUtils.compress(text.getBytes(Charsets.UTF_8));
23+
}
24+
25+
/**
26+
* Gzip a byte array.
27+
*
28+
* @param body
29+
* @return
30+
* @throws IOException
31+
*/
32+
public static byte[] compress(byte[] body) throws IOException {
33+
ByteArrayOutputStream output = new ByteArrayOutputStream();
34+
try {
35+
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(output)) {
36+
gzipOutputStream.write(body);
37+
}
38+
} finally {
39+
output.close();
40+
}
41+
return output.toByteArray();
42+
}
43+
44+
/**
45+
* Decompress a Gzipped byte array to a String.
46+
*
47+
* @param body
48+
* @return
49+
* @throws IOException
50+
*/
51+
public static String decompress(byte[] body) throws IOException {
52+
try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(body))) {
53+
return IOUtils.toString(gzipInputStream, Charsets.UTF_8);
54+
}
55+
}
56+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.eclipse.jetty.server.handler.HandlerCollection;
4+
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
5+
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
9+
/**
10+
* Configure Jetty web server so it handles compressed requests.
11+
*/
12+
@Configuration
13+
public class JettyWebServerConfiguration {
14+
15+
private static final int MIN_BYTES = 1;
16+
17+
/**
18+
* Customise the Jetty web server to automatically decompress requests.
19+
*/
20+
@Bean
21+
public JettyServletWebServerFactory jettyServletWebServerFactory() {
22+
23+
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
24+
factory.addServerCustomizers(server -> {
25+
26+
GzipHandler gzipHandler = new GzipHandler();
27+
// Enable request decompression
28+
gzipHandler.setInflateBufferSize(MIN_BYTES);
29+
gzipHandler.setHandler(server.getHandler());
30+
31+
HandlerCollection handlerCollection = new HandlerCollection(gzipHandler);
32+
server.setHandler(handlerCollection);
33+
});
34+
35+
return factory;
36+
}
37+
38+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
public class Message {
4+
5+
private String text;
6+
7+
public Message() {
8+
}
9+
10+
public Message(String text) {
11+
this.text = text;
12+
}
13+
14+
public String getText() {
15+
return text;
16+
}
17+
18+
public void setText(String text) {
19+
this.text = text;
20+
}
21+
22+
@Override
23+
public String toString() {
24+
final StringBuilder sb = new StringBuilder("Message {");
25+
sb.append("text='").append(text).append('\'');
26+
sb.append('}');
27+
return sb.toString();
28+
}
29+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestBody;
8+
import org.springframework.web.bind.annotation.RequestHeader;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
import java.util.Map;
12+
13+
@RestController
14+
public class MessageController {
15+
16+
protected static final String PROCESSED = "Processed ";
17+
18+
protected static final String REQUEST_MAPPING = "process";
19+
20+
private static final Logger LOG = LoggerFactory.getLogger(MessageController.class);
21+
22+
/**
23+
* A simple endpoint that responds with "Processed " + supplied Message content.
24+
*
25+
* @param headers
26+
* @param message
27+
* @return
28+
*/
29+
@PostMapping(value = REQUEST_MAPPING)
30+
public ResponseEntity<String> processMessage(@RequestHeader Map<String, String> headers,
31+
@RequestBody Message message) {
32+
33+
// Print headers
34+
headers.forEach((k, v) -> LOG.info(k + "=" + v));
35+
36+
return ResponseEntity.ok(PROCESSED + message.getText());
37+
}
38+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.web.client.RestTemplate;
6+
7+
@Configuration
8+
public class RestTemplateConfiguration {
9+
10+
/**
11+
* A RestTemplate that compresses requests.
12+
*
13+
* @return RestTemplate
14+
*/
15+
@Bean
16+
public RestTemplate getRestTemplate() {
17+
RestTemplate restTemplate = new RestTemplate();
18+
restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
19+
return restTemplate;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.baeldung.spring.rest.compress;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
@SpringBootApplication
8+
@EnableAutoConfiguration
9+
public class SpringCompressRequestApplication {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(SpringCompressRequestApplication.class, args);
13+
}
14+
15+
}

0 commit comments

Comments
 (0)