一. Ktor 介绍

Ktor 是一个高性能的、基于 Kotlin 的 Web 开发框架,支持 Kotlin Coroutines、DSL 等特性。

Ktor 是一个由 Kotlin 团队打造的 Web 框架,可用于创建异步、高性能和轻量级的 Web 服务器,并使用 Kotlin 惯用的 API 构建非阻塞的多平台 Web 客户端。

Ktor 的服务端仅限于 JVM,但是 Ktor 的客户端是一个 Multiplatform 的库。

如果使用 Kotlin Multiplatform 构建跨平台项目时,使用 Ktor 的客户端作为 Http 框架是一个不错的选择。

Ktor 由两部分组成:服务器引擎和灵活的异步 HTTP 客户端。当前版本主要集中在 HTTP 客户端上。客户端是一个支持 JVM,JS,Android 和 iOS 的多平台库,现在经常在跨平台移动应用程序中使用。

二. Ktor 服务端的使用

我们可以通过多种方式运行 Ktor 服务端程序:

在 main() 中调用 embeddedServer 来启动 Ktor 应用

运行一个 EngineMain 的 main() 并使用 HOCON application.conf 配置文件

作为 Web 服务器中的 Servlet

在测试中使用 withTestApplication 来启动 Ktor 应用

2.1 Gradle 配置 Ktor

Kotlin 的版本需要 1.3.x,因为 Ktor 底层会依赖到 Kotlin Coroutines。

在需要使用 Ktor 的 module 中添加如下的依赖:

dependencies {

...

implementation "io.ktor:ktor-server-core:${libs.ktor}"

implementation "io.ktor:ktor-server-netty:${libs.ktor}"

}

复制代码

后面的例子还会介绍 Ktor 其他的 artifact,例如:freemarker、gson 等。

2.2 embeddedServer

当使用 embeddedServer 时,Ktor 使用 DSL 来配置应用程序和服务器引擎。目前,Ktor 支持 Netty、Jetty、Tomcat、CIO(Coroutine I/O) 作为服务器引擎。(当然,也支持创建自己的引擎并为其提供自定义配置。)

以 Netty 作为服务器引擎为例,通过 embeddedServer 启动 Ktor 应用:

fun main() {

embeddedServer(Netty, port?:8080, watchPaths = listOf("MainKt"), module = Application::module).start()

}

复制代码

2.3 ApplicationCall && Routing

当一个请求进入 Ktor 应用时(可以是 HTTP,HTTP / 2 或 WebSocket 请求),该请求将被转换为 ApplicationCall 并通过该应用程序拥有的管道。Ktor 的管道是由一个或多个预先安装的拦截器组成,这些拦截器提供某些功能,例如:路由,压缩等,最终将处理请求。

ApplicationCall 提供对两个主要属性 ApplicationRequest 和 ApplicationResponse 的访问。它们对应于传入请求和传出响应。 除了这些之外,ApplicationCall 还提供了一个 ApplicationEnvironment 和一些有用的功能来帮助响应客户端请求。

Routing 是一项安装在应用程序中的功能,用于简化和构建页面请求处理。Ktor 的 Routing 支持 Restful 的各种方法,以及使用 DSL 进行配置。

Routing 支持嵌套,被称为 Routing Tree,可以通过递归匹配复杂的规则和处理请求。

2.4 CORS

默认情况下,Ktor 提供拦截器以实现对跨域资源共享(CORS)的适当支持。

首先,将 CORS 功能安装到应用中。

fun Application.main() {

...

install(CORS)

...

}

复制代码

Ktor CORS 功能的默认配置仅处理 GET,POST 和 HEAD HTTP 方法以及以下标头:

HttpHeaders.Accept

HttpHeaders.AcceptLanguages

HttpHeaders.ContentLanguage

HttpHeaders.ContentType

复制代码

下面的例子展示了如何配置 CORS 功能

fun Application.main() {

...

install(CORS)

{

method(HttpMethod.Options)

header(HttpHeaders.XForwardedProto)

anyHost()

host("my-host")

// host("my-host:80")

// host("my-host", subDomains = listOf("www"))

// host("my-host", schemes = listOf("http", "https"))

allowCredentials = true

allowNonSimpleContentTypes = true

maxAge = Duration.ofDays(1)

}

...

}

复制代码

2.5 Packing

部署 Ktor 应用时,可以使用 fat jar 或者 war 包。

我们以 fat jar 为例,使用 gradle 的 shadow 插件可以方便地打包 Ktor 的应用。

在项目根目录下的 build.gradle 中添加 shadow 插件的依赖:

buildscript {

repositories {

jcenter()

mavenCentral()

}

dependencies {

classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'

......

}

}

复制代码

然后在需要打包的 module 中添加 shadow 插件和输出 jar 包名称以及 jar 包的入口 Main 函数:

plugins {

id 'java'

id 'kotlin'

id 'com.github.johnrengelman.shadow'

}

......

shadowJar {

baseName = 'xxx' // jar 包名称

manifest {

attributes["Main-Class"] = "xxx.xxx.xxx.xxx" // jar 包的主函数

}

}

复制代码

三. 例子

以 RxCache 为例,本文会介绍使用 Ktor 开发一个 Local Cache 的 browser(浏览器),用于读取磁盘缓存中的数据。

RxCache 是一款支持 Java 和 Android 的 Local Cache 。目前支持内存、堆外内存、磁盘缓存。

开发的背景:我们存在一些桌面程序部署在 Ubuntu 上,并需要对这些程序进行埋点,而 RxCache 本身支持磁盘的缓存。因此,我使用 RxCache 存储埋点的数据,所以需要一个浏览器的程序来查看本地的埋点数据。

3.1 RxCache 的配置

RxCache 是一个单例,使用时需要先调用 config() 配置 RxCache。

RxCache 支持二级缓存:Memory、Persistence,并拥有多种序列化方式。这些可以通过配置来体现。

val rxCache: RxCache by lazy {

val converter: Converter = when (Config.converter) {

"gson" -> GsonConverter()。

"fastjson" -> FastJSONConverter()

"moshi" -> MoshiConverter()

"kryo" -> KryoConverter()

"hessian" -> HessianConverter()

"fst" -> FSTConverter()

"protobuf" -> ProtobufConverter()

else -> GsonConverter()

}

RxCache.config {

RxCache.Builder().persistence {

when (Config.type) {

"disk" -> {

val cacheDirectory = File(Config.path) // rxCache 持久层存放地址

if (!cacheDirectory.exists()) {

cacheDirectory.mkdir()

}

DiskImpl(cacheDirectory, converter)

}

"okio" -> {

val cacheDirectory = File(Config.path) // rxCache 持久层存放地址

if (!cacheDirectory.exists()) {

cacheDirectory.mkdir()

}

OkioImpl(cacheDirectory, converter)

}

"mapdb" -> {

val cacheDirectory = File(Config.path) // rxCache 持久层存放地址

MapDBImpl(cacheDirectory, converter)

}

"diskmap"-> {

val cacheDirectory = File(Config.path) // rxCache 持久层存放地址

DiskMapImpl(cacheDirectory, converter)

}

else -> {

val cacheDirectory = File(Config.path) // rxCache 持久层存放地址

if (!cacheDirectory.exists()) {

cacheDirectory.mkdir()

}

DiskImpl(cacheDirectory, converter)

}

}

}

}

RxCache.getRxCache()

}

复制代码

3.2 module

Ktor module 是一个开发者定义的函数,它用于接收 Application 类(该类负责配置服务器管道,安装功能,注册路由,处理请求等)。

在本例子中,安装了 DefaultHeaders、CallLogging、FreeMarker、ContentNegotiation、Routing。

fun Application.module() {

install(DefaultHeaders)

install(CallLogging)

install(FreeMarker) {

templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates")

defaultEncoding = "utf-8"

}

install(ContentNegotiation) {

gson {

setDateFormat(DateFormat.LONG)

setPrettyPrinting()

}

}

install(Routing) {

......

}

}

复制代码

3.3 Routing

Routing 提供了对外的页面。

install(Routing) {

static("/") {

defaultResource("index.html", "web")

}

post("/saveConfig") {

val postParameters: Parameters = call.receiveParameters()

Config.path = postParameters["path"] ?: ""

Config.type = postParameters["type"] ?: ""

Config.converter = postParameters["converter"] ?: ""

call.respond(FreeMarkerContent("save.ftl", mapOf("config" to Config)))

}

get("/list") {

val file = File(Config.path)

val array = file.list()

call.respond(array)

}

get("/detail/{key}") {

val key = call.parameters["key"]

val json = rxCache.getStringData(key)

call.respondText(json)

}

get("/info") {

val json = rxCache.info

call.respondText(json)

}

}

复制代码

其中 index.html 用于配置 RxCache。

saveConfig 用于展示保存的 RxCache 的数据,其中用到了 FreeMarker 的模板 save.ftl

Hi

RxCache's path: ${config.path}

RxCache's persistence: ${config.type}

RxCache's serialization: ${config.converter}

复制代码

list 接口、detail 接口分别用于展示磁盘存储数据的 key,以及根据 key 来查询详细的存储内容。

info 接口用于显示缓存中的信息。

3.4 启动

browser 配置了 kotlinx-cli,它可以通过命令行解析参数。目前,只支持 '-p' 用于表示启动 Ktor 应用的端口号。

browser 使用 Netty 作为服务器引擎。

fun main(args: Array) {

val parser = ArgParser("rxcache-browser")

val port by parser.option(ArgType.Int, shortName = "p", description = "Port number of the local web service")

parser.parse(args)

embeddedServer(Netty, port?:8080, watchPaths = listOf("MainKt"), module = Application::module).start()

}

复制代码

四. 小结

Ktor 构建的应用,只需少量代码和配置即可完成,非常简便。

非常适用于简单的 Web 项目、对外提供接口的 OpenAPI 项目。当然使用它来构建微服务也是可以,它也有丰富的 Features。

ktor框架用到了netty吗_如何使用 Ktor 快速开发 Web 项目相关推荐

  1. ktor框架用到了netty吗_教你如何构建异步服务器和客户端的 Kotlin 框架 Ktor

    Ktor 是一个使用 Kotlin 以最小的成本快速创建 Web 应用程序的框架. Ktor 是一个用于在连接系统(connected systems)中构建异步服务器和客户端的 Kotlin 框架. ...

  2. ktor框架用到了netty吗_Ktor-构建异步服务器和客户端的 Kotlin 框架

    软件简介 Ktor 是一个使用 Kotlin 以最小的成本快速创建 Web 应用程序的框架. Ktor 是一个用于在连接系统(connected systems)中构建异步服务器和客户端的 Kotli ...

  3. ktor框架用到了netty吗_Netty系列相关面试题汇总

    Netty是一个高性能的框架,使用的地方非常多,面试题也经常提问.本套题来源比较多,最主要的来源是ThinkWon,地址是https://thinkwon.blog.csdn.net/article/ ...

  4. javaweb做什么能赚钱_做一个完整的Java Web项目需要掌握的技能

    原文链接:http://blog.csdn.net/JasonLiuLJX/article/details/51494048 最近自己做了几个Java Web项目,有公司的商业项目,也有个人做着玩的小 ...

  5. vue手机端回退_推荐3个快速开发平台 前后端都有 接私活又有着落了

    经常性逛github,发现了一些优秀的开源项目,其中的框架及代码非常不错,现在给大家推荐三个快速开发平台. 第一个就是优秀的Jeecg-boot快速开发平台 前端采用阿里的ant-design-vue ...

  6. python web开发项目 源码_真零基础Python开发web

    Python开发web服务的优势是开发效率高,可能只需要java五分之一的代码量. Python搭建web服务有许多框架,本文介绍Django和bottle两个框架. Django 安装 首先,安装该 ...

  7. 用python写web网页_从零开始,使用python快速开发web站点(1) | 学步园

    环境:ubuntu 12.04 python版本:  2.73 ok,首先,既然是从零开始,我们需要的是一台可以运行的python的计算机环境,并且假设你已经安装好了python, 然后,既然是快速开 ...

  8. java osgi web开发_基于 OSGi 和 Spring 开发 Web 应用

    开发一个简单的OSGi Web应用实例 一个简单的Web应用 我们写一个简单的 Web 应用 compute.html :计算两个数字的和或乘积.如下图所示: 图1.一个简单例子 一个简单例子.bmp ...

  9. 注册登录页面代码用js判断是否填入信息_微信小程序快速开发:从注册账号到小程序上架

    写在前面 自从微信小程序功能发布后,我就一直关注着小程序的动向,然而限于学业繁忙,总是没有太多的时间去学习.大二逐渐学习了Vuejs,被其简洁的设计所吸引,后来看了看小程序的开发文档,发现这么的相似? ...

最新文章

  1. WorldWind Java 版学习:8、事件响应
  2. kafka笔记3(生产者)
  3. 类.接口.多态.向上转型.向下转型
  4. 通过反射获取带参构造方法并使用
  5. 关于struts2在页面请求转发到action的问题
  6. Linux定制history命令的输出格式
  7. 如何时刻保持在目标的正确轨道上
  8. 微信小程序分类小图标导航
  9. GIMP为证件照更换背景颜色
  10. 国内qq邮箱服务器,qq邮箱的服务器在国内吗(注册qq邮箱的服务器是什么)
  11. php 系统分隔符,php脚本由哪个分隔符包围
  12. origin画对数坐标_Origin 画对数坐标图
  13. 使用树莓派连接笔记本热点
  14. java、C语言数组反转
  15. flutter 保存图片或者视频到相册
  16. 宏碁 (ACER) Nitro 笔记本安装Win7系统
  17. Topcoder 2016 TCO Algorithm Algo Semifinal 1 Hard
  18. zabbix迁移部署注意事项
  19. 【JZOJ6384】珂学家
  20. 【新鲜出炉】北达软2011年EA公开课计划-中国EA专家

热门文章

  1. Go进阶(7): JSON 序列化和反序列化
  2. 清理Win7系统的批处理
  3. C语言设计新思维分享
  4. C语言高级技巧-在Makefile中引用你的头文件
  5. 查看使用的那个USB口和开发板通讯
  6. struts2 跳转类型 result type=chain、dispatcher、redirect
  7. 关于JTAG——韦东山嵌入式Linux视频学习笔记02
  8. Head First JSP---随笔八(简单标记)
  9. 二、Netty服务端/客户端启动整体流程
  10. JVM_07 Class文件结构