diff --git a/spring-web-modules/spring-resttemplate-3/README.md b/spring-web-modules/spring-resttemplate-3/README.md index 52eba522a5..3add0073b2 100644 --- a/spring-web-modules/spring-resttemplate-3/README.md +++ b/spring-web-modules/spring-resttemplate-3/README.md @@ -11,3 +11,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Download a Large File Through a Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-download-large-file) - [Access HTTPS REST Service Using Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-secure-https-service) - [Encoding of URI Variables on RestTemplate](https://www.baeldung.com/spring-resttemplate-uri-variables-encode) +- [Difference Between exchange(), postForEntity() and execute() in RestTemplate](https://www.baeldung.com/difference-between-exchange-postForEntity-and-execute) diff --git a/spring-web-modules/spring-resttemplate-3/pom.xml b/spring-web-modules/spring-resttemplate-3/pom.xml index b036a5ffcb..5ce7d348a2 100644 --- a/spring-web-modules/spring-resttemplate-3/pom.xml +++ b/spring-web-modules/spring-resttemplate-3/pom.xml @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/methods/RestTemplateMethodsApplication.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/methods/RestTemplateMethodsApplication.java new file mode 100644 index 0000000000..72201aa5c9 --- /dev/null +++ b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/methods/RestTemplateMethodsApplication.java @@ -0,0 +1,102 @@ +package com.baeldung.resttemplate.methods; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpRequest; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.web.client.RequestCallback; +import org.springframework.web.client.ResponseExtractor; +import org.springframework.web.client.RestTemplate; + +import java.io.IOException; + +/** + * Examples of making the same call with RestTemplate + * using postForEntity(), exchange(), and execute(). + */ +@SpringBootApplication +public class RestTemplateMethodsApplication { + private final static RestTemplate restTemplate = new RestTemplate(); + + public static void main(String[] args) { + + } + + private static void postForEntity() { + Book book = new Book( + "Cruising Along with Java", + "Venkat Subramaniam", + 2023); + + ResponseEntity response = restTemplate.postForEntity( + "https://api.bookstore.com", + book, + Book.class); + } + + private static void exchange() { + Book book = new Book( + "Effective Java", + "Joshua Bloch", + 2001); + + HttpHeaders headers = new HttpHeaders(); + headers.setBasicAuth("username", "password"); + + ResponseEntity response = restTemplate.exchange( + "https://api.bookstore.com", + HttpMethod.POST, + new HttpEntity<>(book, headers), + Book.class); + } + + private static void execute() { + ResponseEntity response = restTemplate.execute( + "https://api.bookstore.com", + HttpMethod.POST, + new RequestCallback() { + @Override + public void doWithRequest(ClientHttpRequest request) throws IOException { + // Create or decorate the request object as needed + } + }, + new ResponseExtractor>() { + @Override + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + // extract required data from response + return null; + } + } + ); + + // Could also use some factory methods in RestTemplate for + // the request callback and/or response extractor + + Book book = new Book( + "Reactive Spring", + "Josh Long", + 2020); + + response = restTemplate.execute( + "https://api.bookstore.com", + HttpMethod.POST, + restTemplate.httpEntityCallback(book), + restTemplate.responseEntityExtractor(Book.class) + ); + } + + private static class Book { + String title; + String author; + int yearPublished; + + public Book(String title, String author, int yearPublished) { + this.title = title; + this.author = author; + this.yearPublished = yearPublished; + } + } +} diff --git a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/resttemplate/methods/RestTemplateMethodsUnitTest.java b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/resttemplate/methods/RestTemplateMethodsUnitTest.java new file mode 100644 index 0000000000..c7a2880f9d --- /dev/null +++ b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/resttemplate/methods/RestTemplateMethodsUnitTest.java @@ -0,0 +1,86 @@ +package com.baeldung.resttemplate.methods; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.*; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.test.web.client.response.MockRestResponseCreators; +import org.springframework.web.client.RestTemplate; + +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; + +/** + * Unit tests for different ways to send POST with RestTemplate. + */ +public class RestTemplateMethodsUnitTest +{ + + private final RestTemplate restTemplate = new RestTemplate(); + + private final String URL = "https://localhost:8080"; + + private MockRestServiceServer mockServer; + + @BeforeEach + public void setup() { + mockServer = MockRestServiceServer.createServer(restTemplate); + } + + /** + * Test that postForEntity sends a POST to the desired URL. + */ + @Test + public void testPostForEntity() { + + mockServer.expect(requestTo(URL)) + .andExpect(method(HttpMethod.POST)) + .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK) + .contentType(MediaType.TEXT_PLAIN) + .body("Ok")); + + restTemplate.postForEntity( + URL, + "Test Body", + String.class); + + mockServer.verify(); + } + + /** + * Test that exchange with POST method sends a POST to the desired URL. + */ + @Test + public void testPostExchange() { + mockServer.expect(requestTo(URL)) + .andExpect(method(HttpMethod.POST)) + .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK) + .contentType(MediaType.TEXT_PLAIN) + .body("Ok")); + + restTemplate.exchange( + URL, + HttpMethod.POST, + new HttpEntity<>("Test Body"), + String.class); + + mockServer.verify(); + } + + @Test + public void testPostExecute() { + mockServer.expect(requestTo(URL)) + .andExpect(method(HttpMethod.POST)) + .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK) + .contentType(MediaType.TEXT_PLAIN) + .body("Ok")); + + restTemplate.execute( + URL, + HttpMethod.POST, + restTemplate.httpEntityCallback("Test body"), + restTemplate.responseEntityExtractor(String.class)); + + mockServer.verify(); + } +}