diff --git a/pom.xml b/pom.xml
index 21d87d9852..005a24effa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -741,6 +741,7 @@
spring-remoting
spring-rest
spring-rest-angular
+ spring-rest-compress
spring-rest-full
spring-rest-hal-browser
spring-rest-query-language
@@ -928,6 +929,7 @@
spring-remoting/remoting-rmi/remoting-rmi-server
spring-rest
spring-rest-angular
+ spring-rest-compress
spring-rest-full
spring-rest-simple
spring-resttemplate
@@ -1433,6 +1435,7 @@
spring-remoting
spring-rest
spring-rest-angular
+ spring-rest-compress
spring-rest-full
spring-rest-hal-browser
spring-rest-query-language
diff --git a/spring-rest-compress/README.md b/spring-rest-compress/README.md
new file mode 100644
index 0000000000..238c28e4b5
--- /dev/null
+++ b/spring-rest-compress/README.md
@@ -0,0 +1,5 @@
+=========================================================================
+## How to compress requests using the Spring RestTemplate Example Project
+
+### Relevant Articles:
+- [How to compress requests using the Spring RestTemplate]()
diff --git a/spring-rest-compress/pom.xml b/spring-rest-compress/pom.xml
new file mode 100644
index 0000000000..d5afc5708d
--- /dev/null
+++ b/spring-rest-compress/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+ com.baeldung
+ spring-rest-compress
+ 0.0.1-SNAPSHOT
+ spring-rest-compress
+
+
+ 1.8
+ 2.6
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jetty
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java
new file mode 100644
index 0000000000..7d5326246d
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java
@@ -0,0 +1,38 @@
+package org.baeldung.spring.rest.compress;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+
+import java.io.IOException;
+
+public class CompressingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CompressingClientHttpRequestInterceptor.class);
+
+ private static final String GZIP_ENCODING = "gzip";
+
+ /**
+ * Compress a request body using Gzip and add Http headers.
+ *
+ * @param req
+ * @param body
+ * @param exec
+ * @return
+ * @throws IOException
+ */
+ @Override
+ public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec)
+ throws IOException {
+ LOG.info("Compressing request...");
+ HttpHeaders httpHeaders = req.getHeaders();
+ httpHeaders.add(HttpHeaders.CONTENT_ENCODING, GZIP_ENCODING);
+ httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING);
+ return exec.execute(req, GzipUtils.compress(body));
+ }
+
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java
new file mode 100644
index 0000000000..f3cb8bd631
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java
@@ -0,0 +1,56 @@
+package org.baeldung.spring.rest.compress;
+
+import org.apache.commons.codec.Charsets;
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+public class GzipUtils {
+
+ /**
+ * Gzip a string.
+ *
+ * @param text
+ * @return
+ * @throws Exception
+ */
+ public static byte[] compress(String text) throws Exception {
+ return GzipUtils.compress(text.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * Gzip a byte array.
+ *
+ * @param body
+ * @return
+ * @throws IOException
+ */
+ public static byte[] compress(byte[] body) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ try {
+ try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(output)) {
+ gzipOutputStream.write(body);
+ }
+ } finally {
+ output.close();
+ }
+ return output.toByteArray();
+ }
+
+ /**
+ * Decompress a Gzipped byte array to a String.
+ *
+ * @param body
+ * @return
+ * @throws IOException
+ */
+ public static String decompress(byte[] body) throws IOException {
+ try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(body))) {
+ return IOUtils.toString(gzipInputStream, Charsets.UTF_8);
+ }
+ }
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java
new file mode 100644
index 0000000000..784814b04d
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java
@@ -0,0 +1,38 @@
+package org.baeldung.spring.rest.compress;
+
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configure Jetty web server so it handles compressed requests.
+ */
+@Configuration
+public class JettyWebServerConfiguration {
+
+ private static final int MIN_BYTES = 1;
+
+ /**
+ * Customise the Jetty web server to automatically decompress requests.
+ */
+ @Bean
+ public JettyServletWebServerFactory jettyServletWebServerFactory() {
+
+ JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
+ factory.addServerCustomizers(server -> {
+
+ GzipHandler gzipHandler = new GzipHandler();
+ // Enable request decompression
+ gzipHandler.setInflateBufferSize(MIN_BYTES);
+ gzipHandler.setHandler(server.getHandler());
+
+ HandlerCollection handlerCollection = new HandlerCollection(gzipHandler);
+ server.setHandler(handlerCollection);
+ });
+
+ return factory;
+ }
+
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java
new file mode 100644
index 0000000000..d3450b227c
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java
@@ -0,0 +1,29 @@
+package org.baeldung.spring.rest.compress;
+
+public class Message {
+
+ private String text;
+
+ public Message() {
+ }
+
+ public Message(String text) {
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Message {");
+ sb.append("text='").append(text).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java
new file mode 100644
index 0000000000..657c3cfec8
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java
@@ -0,0 +1,38 @@
+package org.baeldung.spring.rest.compress;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+public class MessageController {
+
+ protected static final String PROCESSED = "Processed ";
+
+ protected static final String REQUEST_MAPPING = "process";
+
+ private static final Logger LOG = LoggerFactory.getLogger(MessageController.class);
+
+ /**
+ * A simple endpoint that responds with "Processed " + supplied Message content.
+ *
+ * @param headers
+ * @param message
+ * @return
+ */
+ @PostMapping(value = REQUEST_MAPPING)
+ public ResponseEntity processMessage(@RequestHeader Map headers,
+ @RequestBody Message message) {
+
+ // Print headers
+ headers.forEach((k, v) -> LOG.info(k + "=" + v));
+
+ return ResponseEntity.ok(PROCESSED + message.getText());
+ }
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java
new file mode 100644
index 0000000000..e1d0f985d9
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java
@@ -0,0 +1,21 @@
+package org.baeldung.spring.rest.compress;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfiguration {
+
+ /**
+ * A RestTemplate that compresses requests.
+ *
+ * @return RestTemplate
+ */
+ @Bean
+ public RestTemplate getRestTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor());
+ return restTemplate;
+ }
+}
diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java
new file mode 100644
index 0000000000..3082e3c277
--- /dev/null
+++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java
@@ -0,0 +1,15 @@
+package org.baeldung.spring.rest.compress;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableAutoConfiguration
+public class SpringCompressRequestApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringCompressRequestApplication.class, args);
+ }
+
+}
diff --git a/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java
new file mode 100644
index 0000000000..d238c9ec7c
--- /dev/null
+++ b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java
@@ -0,0 +1,19 @@
+package org.baeldung.spring.rest.compress;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class GzipUtilsUnitTest {
+
+ @Test
+ public void givenCompressedText_whenDecompressed_thenSuccessful() throws Exception {
+ final String expectedText = "Hello Baeldung!";
+ byte[] compressedText = GzipUtils.compress(expectedText);
+ String decompressedText = GzipUtils.decompress(compressedText);
+ assertNotNull(compressedText);
+ assertEquals(expectedText, decompressedText);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java
new file mode 100644
index 0000000000..9658204917
--- /dev/null
+++ b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java
@@ -0,0 +1,56 @@
+package org.baeldung.spring.rest.compress;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.client.RestTemplate;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class MessageControllerUnitTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MessageControllerUnitTest.class);
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ /**
+ * As a further test you can intercept the request body, using a tool like
+ * Wireshark, to see the request body is actually gzipped.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void givenRestTemplate_whenPostCompressedRequest_thenRespondsSuccessfully() throws Exception {
+
+ final String text = "Hello Baeldung!";
+ Message message = new Message(text);
+
+ HttpEntity request = new HttpEntity<>(message);
+ String uri = String.format("http://localhost:%s/%s", randomServerPort, MessageController.REQUEST_MAPPING);
+
+ ResponseEntity responseEntity = restTemplate.postForEntity(uri, request, String.class);
+
+ String response = responseEntity.getBody();
+ LOG.info("Got response [{}]", response);
+
+ assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ assertNotNull(response);
+ assertEquals(MessageController.PROCESSED + text, response);
+ }
+
+}