Ktor
这是一个由 Kotlin 团队打造的 Web 框架,可用于创建异步、高性能和轻量级的 Web 服务器,并使用 Kotlin 惯用的 API 构建非阻塞的多平台 Web 客户端,由于 DSL 的存在,使得在 Ktor 下编写代码尤如写配置,非常的方便灵活。
上面这句是抄的!
在实际开发中,我们需要将 Ktor 程序部署到容器内运行,比如说 tomcat。然而使用 Idea 内的 Ktor 向导创建的 tomcat 项目并不能让我们如愿,具体的不多说了,自己创建一下便知。那这篇的目的很简单了,就是让官方提供的那个超简单的 demo 在 tomcat 上跑起来。
官方的 demo 到底有多简单呢?看以下代码就可以了:
package io.ktor.sample
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
fun main(args: Array<String>) {
val server = embeddedServer(Netty, port = 8080) {
routing {
get("/") {
call.respondText("Hello World!", ContentType.Text.Plain)
}
get("/demo") {
call.respondText("HELLO WORLD!")
}
}
}
server.start(wait = true)
}
可以看到,它使用了嵌入的 netty 服务器,如果我们要在 tomcat 上运行,必然不能用它了,删掉之,直接使用 routing
。
fun Application.main() {
routing {
get("/") {
call.respondText("Hello World!", ContentType.Text.Plain)
}
get("/demo") {
call.respondText("HELLO WORLD!")
}
}
}
很简单的了,接下去就是如何运行的问题。很可惜的,依然要吐槽一下官方的向导,通过它建立起来的工程并不能够直接运行于 tomcat,需要自己做一些修改。
首先要增加 web/WEB-INF
目录,它与 src
目录是同级的,然后编写 web.xml
文件,在这里有个好消息,用于 Ktor
的 web.xml
是固定不变的,照抄就好:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<display-name>KtorServlet</display-name>
<servlet-name>KtorServlet</servlet-name>
<servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>
<init-param>
<param-name>io.ktor.config</param-name>
<param-value>application.conf</param-value>
</init-param>
<async-supported>true</async-supported>
<multipart-config>
<max-file-size>304857600</max-file-size>
<max-request-size>304857600</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>KtorServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
在这个配置内,你可以自己修改最大的文件上传和请求的 size,其他的东西都无须变动。
接下来修改一下 application.conf
文件,它位于 resources
目录下,对于 Ktor
程序来说,resources
目录非常重要,你可以把一切静态内容都扔进去。
ktor {
application {
modules = [ io.ktor.sample.ApplicationKt.main ]
}
}
只需要改这一句就可以了,它的组成格式为 包名.类名.函数名
,需要注意的是,针对一个没有 class
声明的 Kotlin 文件,它在编译后会生成形如 文件名Kt
的 .class
文件,这也是配置 内 ApplicationKt
的由来。
最后一步,编写 build.gradle
,这个脚本主要做两件事,一件是将工程打包为 war 包,另一件是帮助调试运行,再次说一句可惜,因为官方的向导依然没能帮助我们完成这些(怎么一直在吐槽2333)。
buildscript {
ext.ktor_version = "1.1.2"
ext.kotlin_version = "1.3.20"
ext.tomcat_plugin_version = "2.4.2"
ext.tomcat_version = "9.0.4"
ext.slf4j_version = "1.7.25"
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/kotlin/ktor' }
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.bmuschko:gradle-tomcat-plugin:$tomcat_plugin_version"
}
}
apply plugin: "kotlin"
apply plugin: "war"
apply plugin: 'com.bmuschko.tomcat'
webAppDirName = "web"
tomcat {
contextPath = "/"
httpProtocol = "org.apache.coyote.http11.Http11Nio2Protocol"
ajpProtocol = "org.apache.coyote.ajp.AjpNio2Protocol"
}
sourceSets {
main.kotlin.srcDirs = ["src"]
main.resources.srcDirs = ["resources"]
}
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-servlet:$ktor_version"
compile "io.ktor:ktor-html-builder:$ktor_version"
compile "org.slf4j:slf4j-jdk14:$slf4j_version"
tomcat "org.apache.tomcat.embed:tomcat-embed-core:$tomcat_version",
"org.apache.tomcat.embed:tomcat-embed-jasper:$tomcat_version"
}
task run(dependsOn: tomcatRun)
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental"]
}
完整的 gradle 文件如上,暂时不要管那么多,跑就是了!
$ gradle clean build // 可以完成一个 war 包的编译
$ gradle run // 可以将项目运行于 tomcat
运行后,只需要访问 http://localhost:8080
就可以看到我们的页面了,本篇也到此先告一段落。
下一篇预告:《Ktor 从入门到放弃(二) 项目结构与文件访问》