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>maven-archetype</module>
|
||||
<module>apache-meecrowave</module>
|
||||
<module>spring-reactive-kotlin</module>
|
||||
<module>jnosql</module>
|
||||
</modules>
|
||||
|
||||
|
@ -734,6 +735,7 @@
|
|||
<module>spring-rest-query-language</module>
|
||||
<module>spring-rest</module>
|
||||
<module>spring-rest-simple</module>
|
||||
<module>spring-reactive-kotlin</module>
|
||||
|
||||
|
||||
<!-- 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