使用RouterFunctions使用Kotlin + Spring boot2 + Webflux + Thymeleaf进行实现

首先

我正在尝试将我在家里的开发环境中使用Java的部分改成Kotlin。
这是我试着创建的备忘录,目的是在这个过程中先暂时建立类似标题中所提到的环境。

环境

IntelliJ IDEA
Kotlin 1.2.20
Java 8
Spring Boot 2.0.0.RELEASE

智能IDEA
Kotlin 1.2.20
Java 8
Spring Boot 2.0.0.RELEASE

项目准备

这次我们将使用Initializer来简化操作。因为听说在IntelliJ中只有付费版才能创建Spring项目,所以我们决定从网上进行创建。至于依赖项,我们可以稍后添加,所以可以是空的也可以添加进去。

构建.gradle

1. 春季引导器
2. 春季引导器-Webflux
3. 春季引导器-Thymeleaf

在创建代码时,即使没有thymeleaf,也可以想办法解决。但是在运行时出现错误,而且完全不知道错误的原因,所以最好小心一点(耗时3小时)。

只需要将其添加到由Initializer创建的工具中。但是,我会附上当它成功运行时的全部build.gradle文件。

buildscript {
    ext {
        kotlinVersion = '1.2.20'
        springBootVersion = '2.0.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
        classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.tasogarei'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-webflux')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    compile("org.jetbrains.kotlin:kotlin-reflect")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

应用程序类

那么,我们开始实施。首先是运行引导程序的主类。

在这个例子中,我想试试使用REACTIVE,所以我使用了SpringApplicationBuilder来创建,但是使用SpringApplication.run(Application::class.java,*args)也可以运行。

package com.tasogarei.application

import org.springframework.boot.WebApplicationType
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder

@SpringBootApplication
class Application

fun main(args: Array<String>) {
    SpringApplicationBuilder()
            .sources(Application::class.java)
            .web(WebApplicationType.REACTIVE)
            .run(*args)
}

处理程序类

我們將創建一個處理請求的Handler。由於這次想返回HTML,所以我們使用HTML作為ContentType並使用render返回View。View的位置規則與不使用WebFlux時相同。

由于这只是一个试验,所以我们可以省略将attribute作为Map传递给render函数的步骤。

package com.tasogarei.application.handler

import org.springframework.http.MediaType
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Mono

@Component
class Handler {
    fun getIndex(req: ServerRequest): Mono<ServerResponse> {
        return ServerResponse.ok().contentType(MediaType.TEXT_HTML).render("index")
    }
}

创建RouterFunction。

我会创建一个RouterFunction。
通过创建RouterFunction,可以将所有的Mapping集中起来,所以我个人更喜欢这种方式,而不是在Controller上一个一个地进行Mapping。

不知怎么地,通过使用 accept 和 nest 等方法来处理复杂的 URL 结构,但只需写上 GET(“/”, handler::getIndex) 就能运行。
嗯,我认为对于一般的 Web 应用程序,由于很快就会增加,所以最好一开始就写得容易添加。

此外,还通过传递使用的Handler,可以在函数侧面上像routeIndex(handler: Handler)一样添加。当Handler增加时,我觉得不应该像构造函数的示例一样写,而是应该增加函数。但我不确定哪个更好。

package com.tasogarei.application.route

import com.tasogarei.application.handler.Handler
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.router

@Configuration
class Route(private val handler: Handler) {
    @Bean
    fun routeIndex() = router {
        accept(MediaType.TEXT_HTML).nest {
            GET("/", handler::getIndex)
        }
    }
}

确认行动

只需放置相应的HTML并启动浏览器进行访问,就能够看到内容了。

最后

虽然我刚开始对Dependency出现了错误而感到困惑,但现在我已经能够轻松地使用Webflux处理HTML了。
我知道使用或不使用Webflux都有其优缺点,但根据个人喜好,我打算继续使用它一段时间。

广告
将在 10 秒后关闭
bannerAds