Merge pull request #4710 from veontomo/SpringReactiveKotlin
Code for the article "Spring Webflux with Kotlin"
This commit is contained in:
commit
c024537ed2
2
pom.xml
2
pom.xml
|
@ -545,6 +545,7 @@
|
||||||
<module>antlr</module>
|
<module>antlr</module>
|
||||||
<module>maven-archetype</module>
|
<module>maven-archetype</module>
|
||||||
<module>apache-meecrowave</module>
|
<module>apache-meecrowave</module>
|
||||||
|
<module>spring-reactive-kotlin</module>
|
||||||
<module>jnosql</module>
|
<module>jnosql</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
@ -734,6 +735,7 @@
|
||||||
<module>spring-rest-query-language</module>
|
<module>spring-rest-query-language</module>
|
||||||
<module>spring-rest</module>
|
<module>spring-rest</module>
|
||||||
<module>spring-rest-simple</module>
|
<module>spring-rest-simple</module>
|
||||||
|
<module>spring-reactive-kotlin</module>
|
||||||
|
|
||||||
|
|
||||||
<!-- group 3.2 - Pass, 8 minutes, 1 failed test, 2,294 KB log -->
|
<!-- group 3.2 - Pass, 8 minutes, 1 failed test, 2,294 KB log -->
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?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>springreactivekotlin</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>springreactivekotlin</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<kotlin.version>1.2.41</kotlin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-kotlin</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<configuration>
|
||||||
|
<args>
|
||||||
|
<arg>-Xjsr305=strict</arg>
|
||||||
|
</args>
|
||||||
|
<compilerPlugins>
|
||||||
|
<plugin>spring</plugin>
|
||||||
|
</compilerPlugins>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-allopen</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
class Application
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
SpringApplication.run(Application::class.java, *args)
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody
|
||||||
|
import reactor.core.publisher.Flux
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
class Controller {
|
||||||
|
|
||||||
|
@GetMapping(path = ["/numbers"], produces = [MediaType.APPLICATION_STREAM_JSON_VALUE])
|
||||||
|
@ResponseBody
|
||||||
|
fun getNumbers(): Flux<Int> {
|
||||||
|
return Flux.range(1, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
class Device(val name: String, val reading: Double) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.web.reactive.function.BodyInserters.fromObject
|
||||||
|
import org.springframework.web.reactive.function.server.ServerRequest
|
||||||
|
import org.springframework.web.reactive.function.server.ServerResponse
|
||||||
|
import reactor.core.publisher.Mono
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class HomeSensorsHandler {
|
||||||
|
|
||||||
|
var data = mapOf("lamp" to arrayOf(0.7, 0.65, 0.67), "fridge" to arrayOf(12.0, 11.9, 12.5))
|
||||||
|
|
||||||
|
fun setLight(request: ServerRequest): Mono<ServerResponse> = ServerResponse.ok().build()
|
||||||
|
|
||||||
|
fun getLightReading(request: ServerRequest): Mono<ServerResponse> =
|
||||||
|
ServerResponse.ok().body(fromObject(data["lamp"]!!))
|
||||||
|
|
||||||
|
fun getDeviceReadings(request: ServerRequest): Mono<ServerResponse> {
|
||||||
|
val id = request.pathVariable("id")
|
||||||
|
return ServerResponse.ok().body(fromObject(Device(id, 1.0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllDevices(request: ServerRequest): Mono<ServerResponse> =
|
||||||
|
ServerResponse.ok().body(fromObject(arrayOf("lamp", "tv")))
|
||||||
|
|
||||||
|
fun getAllDeviceApi(request: ServerRequest): Mono<ServerResponse> =
|
||||||
|
ServerResponse.ok().body(fromObject(arrayListOf("kettle", "fridge")))
|
||||||
|
|
||||||
|
fun setDeviceReadingApi(request: ServerRequest): Mono<ServerResponse> {
|
||||||
|
return request.bodyToMono(Device::class.java).flatMap { it ->
|
||||||
|
ServerResponse.ok().body(fromObject(Device(it.name.toUpperCase(), it.reading)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.http.MediaType.APPLICATION_JSON
|
||||||
|
import org.springframework.http.MediaType.TEXT_HTML
|
||||||
|
import org.springframework.web.reactive.function.server.router
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class HomeSensorsRouters(private val handler: HomeSensorsHandler) {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun roomsRouter() = router {
|
||||||
|
(accept(TEXT_HTML) and "/room").nest {
|
||||||
|
GET("/light", handler::getLightReading)
|
||||||
|
POST("/light", handler::setLight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun deviceRouter() = router {
|
||||||
|
accept(TEXT_HTML).nest {
|
||||||
|
(GET("/device/") or GET("/devices/")).invoke(handler::getAllDevices)
|
||||||
|
GET("/device/{id}", handler::getDeviceReadings)
|
||||||
|
}
|
||||||
|
(accept(APPLICATION_JSON) and "/api").nest {
|
||||||
|
(GET("/device/") or GET("/devices/")).invoke(handler::getAllDeviceApi)
|
||||||
|
POST("/device/", handler::setDeviceReadingApi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.springreactivekotlin
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.web.reactive.function.server.ServerResponse
|
||||||
|
import org.springframework.web.reactive.function.server.router
|
||||||
|
|
||||||
|
import org.springframework.web.reactive.function.BodyInserters.fromObject
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class SimpleRoute {
|
||||||
|
@Bean
|
||||||
|
fun route() = router {
|
||||||
|
GET("/route") { _ -> ServerResponse.ok().body(fromObject(arrayOf(1, 2, 3))) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package veontomo
|
||||||
|
|
||||||
|
import com.baeldung.springreactivekotlin.SimpleRoute
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient
|
||||||
|
|
||||||
|
class RoutesTest {
|
||||||
|
|
||||||
|
lateinit var client: WebTestClient
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun init() {
|
||||||
|
this.client = WebTestClient.bindToRouterFunction(SimpleRoute().route()).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenRequestToRoute_thenStatusShouldBeOk() {
|
||||||
|
client.get()
|
||||||
|
.uri("/route")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isOk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenRequestToRoute_thenBodyShouldContainArray123() {
|
||||||
|
client.get()
|
||||||
|
.uri("/route")
|
||||||
|
.exchange()
|
||||||
|
.expectBody()
|
||||||
|
.json("[1, 2, 3]")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue