Skip to content

Dashboard

Spring Reactive on latest technologies stack (JDK 17, Spring Boot 2.6.0)

Created by Admin

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

Source: https://viblo.asia/p/spring-reactive-on-latest-technologies-stack-jdk-17-spring-boot-260-Eb85ozw0l2G