In this article, I create a sample use Spring Reactive on latest technologies stack: JDK 17, Gradle 7.3 , IntelliJ IDEA 2021.2.3 Ultimate, Spring Boot 2.6.0
, Spring dependency management 1.0.11.RELEASE
.
Check environment
C:\Users\donhu>gradle -v
------------------------------------------------------------
Gradle 7.3
------------------------------------------------------------
Build time: 2021-11-09 20:40:36 UTC
Revision: 96754b8c44399658178a768ac764d727c2addb37
Kotlin: 1.5.31
Groovy: 3.0.9
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 17.0.1 (Oracle Corporation 17.0.1+12-LTS-39)
OS: Windows 10 10.0 amd64
C:\Users\donhu>
JDK
C:\Users\donhu>java --version
java 17.0.1 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)
C:\Users\donhu>javac --version
javac 17.0.1
C:\Users\donhu>
File build.gradle
plugins {
id 'org.springframework.boot' version '2.6.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '17'
targetCompatibility = '17'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
test {
useJUnitPlatform()
}
File Application.java
package employee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
EmployeeClient employeeClient = context.getBean(EmployeeClient.class);
System.out.println(">>> Client called: " + employeeClient.getMessage().block());
}
}
File application.properties
server.port=8087
File Employee.java
package employee;
import java.util.Objects;
public class Employee {
private String firstName;
private String lastName;
private String dateOfBirth;
public Employee() {
}
public Employee(String firstName, String lastName, String dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(firstName, employee.firstName) && Objects.equals(lastName, employee.lastName) && Objects.equals(dateOfBirth, employee.dateOfBirth);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, dateOfBirth);
}
}
File EmployeeHandler.java
package employee;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class EmployeeHandler {
public Mono<ServerResponse> getInfo(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(new Employee("Vy", "Do Nhu", "26/08/1987")));
}
}
File EmployeeRouter.java
package employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
@Configuration(proxyBeanMethods = false)
public class EmployeeRouter {
@Bean
public RouterFunction<ServerResponse> route(EmployeeHandler employeeHandler) {
return RouterFunctions.route(GET("/employee").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::getInfo);
}
}
File EmployeeClient.java
package employee;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Component
public class EmployeeClient {
private final WebClient client;
public EmployeeClient(WebClient.Builder builder) {
this.client = builder.baseUrl("http://localhost:8087").build();
}
public Mono<String> getMessage() {
return this.client.get().uri("/employee").accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Employee.class)
.map(Employee::toString);
}
}
Run project
Test RESTful API by Postman
Source code: https://github.com/donhuvy/sample_spring_reactive.git