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