Ktor入门 -- 项目搭建与启动

前言

Ktor是使用kotlin语音写的一个高性能web框架, 你可以类比认为 Tomcat 服务器.
本篇只是简单的说明 如何启动一个web服务 ,

项目结构

项目使用Gradle管理, 整个项目结果如下:
在这里插入图片描述

Gradle的包依赖管理

定义了kotlin 和 ktor的版本 , 并且引入了日志框架logback 和我最喜欢的工具包hutool

项目的最外部的build.gradle文件的内容如下:

buildscript {
    ext {
        kotlin_version = '1.5.30'
        ktor_version = '1.6.7'
    }
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

subprojects {
    apply plugin: "idea"
    apply plugin: "kotlin"

    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11

    repositories {
        mavenLocal()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        mavenCentral()
        jcenter()
    }

    dependencies {
        compile "ch.qos.logback:logback-classic:1.2.5"
        compile "cn.hutool:hutool-all:5.7.10"
        compile "org.jetbrains.kotlin:kotlin-stdlib"
    }
}

nexus模块

build.gradle文件

其中 ktor 开头的包都是 相关的包, hibernate和postgresql相关的包入门的时候可以先删除, 后面我会接入hibernate和postgresql的.

plugins {
    id 'kotlin'
    id 'application'
}

group 'com.github.blanexie'
version '1.0-SNAPSHOT'

application {
    mainClass = 'com.github.blanexie.nexusj.AppKt'
}

dependencies {

    implementation 'org.postgresql:postgresql:42.3.3'
    implementation 'org.hibernate:hibernate-core:5.6.5.Final'

    implementation "io.ktor:ktor-server-core:$ktor_version"
    implementation "io.ktor:ktor-server-netty:$ktor_version"

    implementation "io.ktor:ktor-auth:$ktor_version"
    implementation "io.ktor:ktor-auth-jwt:$ktor_version"

    implementation "io.ktor:ktor-gson:$ktor_version"

    testImplementation "io.ktor:ktor-server-test-host:$ktor_version"
    testImplementation "org.jetbrains.kotlin:kotlin-test"
}

test {
    useJUnitPlatform()
}

resource目录下的application.conf文件

这个是ktor的配置文件, 其中定义了端口号等信息, 也定义了jwt鉴权相关的信息.

ktor {
    development = true
    deployment {
        port = 8080
        autoreload = true
    }
    application {
        modules = [ com.github.blanexie.nexusj.AppKt.module ]
        watch = [ com.github.blanexie.nexusj ]
    }
}

jwt {
    domain = "https://jwt-provider-domain/"
    audience = "jwt-audience"
    realm = "ktor sample app"
}

App启动类

在这里插入图片描述

package com.github.blanexie.nexusj

import com.github.blanexie.nexusj.support.Auth
import com.github.blanexie.nexusj.support.Config
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.auth.jwt.*
import io.ktor.features.*
import io.ktor.gson.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import java.text.DateFormat
import javax.persistence.EntityManagerFactory
import javax.persistence.Persistence
import javax.persistence.PersistenceUnit


fun main(args: Array<String>): Unit {
    io.ktor.server.netty.EngineMain.main(args)
}

fun Application.module(testing: Boolean = true) {
    Config.build(environment)
	
	//响应自动完善请求头
    install(AutoHeadResponse)
    //启用压缩
    install(Compression)
    //启用日志打印
    install(CallLogging)
    //json序列化设置, 使用了gson 
    install(ContentNegotiation) {
        gson {
            setDateFormat(DateFormat.LONG)
            setPrettyPrinting()
        }
    }

    //跨域设置
    install(CORS) {
        method(HttpMethod.Options)
        method(HttpMethod.Get)
        method(HttpMethod.Post)
        method(HttpMethod.Put)
        method(HttpMethod.Delete)
        method(HttpMethod.Patch)

        header(HttpHeaders.Authorization)
        header(HttpHeaders.ContentType)

        allowCredentials = true
        allowNonSimpleContentTypes = true
        //允许跨域的域名. 最新版本的必须要指定需要跨域的域名
        host("localhost")
    }
	//JWT鉴权
    install(Authentication) {
        jwt {
            verifier(Auth.verifier)
            validate {
                JWTPrincipal(it.payload)
            }
        }
    }
	//路由设置
    routing {
        route("/announce") {
            get() {
                val uri = call.request.uri
                //生成jwt的token
                val token= Auth.makeToken("xiezc")
                //获取配置文件的信息
                val domain = Config.getConfig().getStringOrNull("jwt.domain")
                call.respondText("Request uri: $uri ;  $token; $domain")
            }
        }
		//需要鉴权访问的路由
        route("/api/nexus") {
            authenticate {
                get("/test") {
                    val uri = call.request.uri
                    call.respondText("Request uri: $uri")
                }
            }
        }
    }
	//拦截器的配置
    intercept(ApplicationCallPipeline.Call) {
        if (call.request.uri == "/") {
            call.respondText("Test String")
        }
    }
}

上面的代码配置了两个路由, 一个拦截器, 我们访问下:

http://localhost:8080/announce token也生成了, domain配置文件的信息也获取到了
在这里插入图片描述
http://localhost:8080/ 返回了拦截器的信息
在这里插入图片描述
http://localhost:8080/api/nexus/test 鉴权生效了
在这里插入图片描述

Auth类代码

这个类中主要是jwt相关的代码

package com.github.blanexie.nexusj.support

import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.auth0.jwt.interfaces.JWTVerifier
import java.util.*

object Auth {

   private const val SECRET_KEY = "secret"
   private val algorithm = Algorithm.HMAC512(SECRET_KEY)
   private const val issuer = "ktor.io"
   private const val validityInMs = 3600 * 1000 * 72 // 72 hours
   val verifier = JWT
       .require(algorithm)
       .withIssuer(issuer)
       .build()!!
       
   //生成token
   fun makeToken(name: String): String = JWT.create()
       .withSubject("Authentication")
       .withIssuer(issuer)
       .withClaim("name", name)
       .withExpiresAt(getExpiration())
       .sign(algorithm)

   private fun getExpiration() = Date(System.currentTimeMillis() + validityInMs)
}

Config 配置类

获取ktor中配置文件信息的工具类

package com.github.blanexie.nexusj.support

import io.ktor.application.*

/**
 * 配置信息
 *
 * @author     :xiezc
 * @date       :2022/2/28 3:05 PM
 */
class Config(val environment: ApplicationEnvironment) {

    companion object {
        private var config: Config? = null
        fun build(environment: ApplicationEnvironment): Config {
            this.config = Config(environment)
            return this.config!!
        }

        fun getConfig(): Config {
            return this.config!!
        }
    }

    fun getString(key: String): String {
        return environment.config.property(key).getString();
    }

    fun getStringOrNull(key: String): String? {
        return environment.config.propertyOrNull(key)?.getString();
    }

    fun getList(key: String): List<String> {
        return environment.config.property(key).getList();
    }

    fun getListOrNull(key: String): List<String>? {
        return environment.config.propertyOrNull(key)?.getList();
    }
}

启动

在这里插入图片描述

结尾

ktor的文档地址:
https://ktor.kotlincn.net/servers/application.html

可以参考这个文档地址 进行一些个性化的改造, 比如:

  1. 序列化使用jackson等.
  2. 鉴权方式使用basic等

本篇只是简单搭起一个可以运行的web服务, 后面还要接入hibernate和数据库postgresql

敬请期待

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ktor和Spring WebFlux都是基于响应式编程的Web框架,它们具有许多相似之处,但也有一些区别。 1. 学习曲线 Ktor比Spring WebFlux的学习曲线更平滑,因为它的API更简洁,更容易理解和使用。它的DSL(领域特定语言)方式使得开发人员可以更快地编写代码,而不必了解太多的框架细节。然而,Spring WebFlux的学习曲线可能更陡峭,因为它是一个更大的框架,需要更多的学习和理解。 2. 性能 Ktor比Spring WebFlux在性能方面表现更好,因为它是一个更轻量级的框架。它可以处理更高的并发请求并具有更快的响应时间。然而,Spring WebFlux也具有很好的性能,并且可以轻松扩展到更大的应用程序。 3. 路由 Ktor的路由系统简单,易于使用,并且可以轻松地将路由映射到不同的处理程序。然而,Spring WebFlux的路由系统更加灵活,可以更好地处理复杂的路由映射。它还支持更多的路由选项,如正则表达式和路径变量。 4. 生态系统 Spring WebFlux具有更大的生态系统,因为它是Spring Framework的一部分。它有许多可用的插件和库,可以轻松地与其他Spring项目集成。另一方面,Ktor是一个相对较新的框架,它的生态系统较小,但它也有一些可用的插件和库。 综上所述,Ktor和Spring WebFlux都是优秀的Web框架,具有各自的优点和缺点。选择哪一个取决于您的需求和技术水平。如果您需要一个轻量级的框架,快速开发,并需要更好的性能,则Ktor可能是更好的选择。如果您需要一个更灵活的框架,并且已经熟悉了Spring Framework,则Spring WebFlux可能更适合您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值