BAEL-3007: WebClient vs RestTemplate example.
This commit is contained in:
parent
01a447d6d3
commit
04e9fdafa4
3
pom.xml
3
pom.xml
|
@ -606,6 +606,7 @@
|
||||||
<module>spring-5-data-reactive</module>
|
<module>spring-5-data-reactive</module>
|
||||||
<module>spring-5-mvc</module>
|
<module>spring-5-mvc</module>
|
||||||
<module>spring-5-reactive</module>
|
<module>spring-5-reactive</module>
|
||||||
|
<module>spring-5-reactive-2</module>
|
||||||
<module>spring-5-reactive-client</module>
|
<module>spring-5-reactive-client</module>
|
||||||
<module>spring-5-reactive-oauth</module>
|
<module>spring-5-reactive-oauth</module>
|
||||||
<module>spring-5-reactive-security</module>
|
<module>spring-5-reactive-security</module>
|
||||||
|
@ -820,6 +821,7 @@
|
||||||
<module>spring-5</module>
|
<module>spring-5</module>
|
||||||
<module>spring-5-data-reactive</module>
|
<module>spring-5-data-reactive</module>
|
||||||
<module>spring-5-reactive</module>
|
<module>spring-5-reactive</module>
|
||||||
|
<module>spring-5-reactive-2</module>
|
||||||
<module>spring-5-reactive-client</module>
|
<module>spring-5-reactive-client</module>
|
||||||
<module>spring-5-reactive-security</module>
|
<module>spring-5-reactive-security</module>
|
||||||
<module>spring-5-security</module>
|
<module>spring-5-security</module>
|
||||||
|
@ -1277,6 +1279,7 @@
|
||||||
<module>spring-5-data-reactive</module>
|
<module>spring-5-data-reactive</module>
|
||||||
<module>spring-5-mvc</module>
|
<module>spring-5-mvc</module>
|
||||||
<module>spring-5-reactive</module>
|
<module>spring-5-reactive</module>
|
||||||
|
<module>spring-5-reactive-2</module>
|
||||||
<module>spring-5-reactive-client</module>
|
<module>spring-5-reactive-client</module>
|
||||||
<module>spring-5-reactive-oauth</module>
|
<module>spring-5-reactive-oauth</module>
|
||||||
<module>spring-5-reactive-security</module>
|
<module>spring-5-reactive-security</module>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#folders#
|
||||||
|
.idea
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
|
@ -0,0 +1 @@
|
||||||
|
## Spring 5 Reactive Project
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-5-reactive-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>spring-5-reactive-2</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>spring 5 sample project about new features</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.baeldung.webclient.WebClientApplication</mainClass>
|
||||||
|
<layout>JAR</layout>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.webclient;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Tweet {
|
||||||
|
private String text;
|
||||||
|
private String username;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.webclient;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class TweetsSlowServiceController {
|
||||||
|
|
||||||
|
@GetMapping("/slow-service-tweets")
|
||||||
|
private List<Tweet> getAllTweets() throws Exception {
|
||||||
|
Thread.sleep(2000L); // delay
|
||||||
|
return Arrays.asList(
|
||||||
|
new Tweet("RestTemplate rules", "@user1"),
|
||||||
|
new Tweet("WebClient is better", "@user2"),
|
||||||
|
new Tweet("OK, both are useful", "@user1"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.webclient;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class WebClientApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(WebClientApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.webclient;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class WebController {
|
||||||
|
|
||||||
|
private static final int DEFAULT_PORT = 8080;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private int serverPort = DEFAULT_PORT;
|
||||||
|
|
||||||
|
@GetMapping("/tweets-blocking")
|
||||||
|
public List<Tweet> getTweetsBlocking() {
|
||||||
|
log.info("Starting BLOCKING Controller!");
|
||||||
|
final String uri = getSlowServiceUri();
|
||||||
|
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
ResponseEntity<List<Tweet>> response = restTemplate.exchange(
|
||||||
|
uri, HttpMethod.GET, null,
|
||||||
|
new ParameterizedTypeReference<List<Tweet>>(){});
|
||||||
|
|
||||||
|
List<Tweet> result = response.getBody();
|
||||||
|
result.forEach(tweet -> log.info(tweet.toString()));
|
||||||
|
log.info("Exiting BLOCKING Controller!");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/tweets-non-blocking", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
|
public Flux<Tweet> getTweetsNonBlocking() {
|
||||||
|
log.info("Starting NON-BLOCKING Controller!");
|
||||||
|
Flux<Tweet> tweetFlux = WebClient.create()
|
||||||
|
.get()
|
||||||
|
.uri(getSlowServiceUri())
|
||||||
|
.retrieve()
|
||||||
|
.bodyToFlux(Tweet.class);
|
||||||
|
|
||||||
|
tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
|
||||||
|
log.info("Exiting NON-BLOCKING Controller!");
|
||||||
|
return tweetFlux;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSlowServiceUri() {
|
||||||
|
return "http://localhost:" + serverPort + "/slow-service-tweets";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.webclient;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WebClientApplication.class)
|
||||||
|
public class WebControllerIntegrationTest {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
int randomServerPort;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebTestClient testClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebController webController;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
webController.setServerPort(randomServerPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenEndpointWithBlockingClientIsCalled_thenThreeTweetsAreReceived() {
|
||||||
|
testClient.get()
|
||||||
|
.uri("/tweets-blocking")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBodyList(Tweet.class)
|
||||||
|
.hasSize(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenEndpointWithNonBlockingClientIsCalled_thenThreeTweetsAreReceived() {
|
||||||
|
testClient.get()
|
||||||
|
.uri("/tweets-non-blocking")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isOk()
|
||||||
|
.expectBodyList(Tweet.class)
|
||||||
|
.hasSize(3);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue