美文网首页
Ktor-开发实用技巧获(1)-获取put/delete请求bo

Ktor-开发实用技巧获(1)-获取put/delete请求bo

作者: 东阿 | 来源:发表于2020-01-05 15:37 被阅读0次

    Ktor 是一个使用强大的 Kotlin 语言在互联系统中构建异步服务器与客户端的框架。
    Ktor 有十分好用的语法糖,可以快速的声明一个接口。
    但是,Ktor 默认对 put 和delete的请求支持 不是很好,主要是Ktor默认只能解析put和delete请求的 url 参数,无法像post请求一样获取body里的参数,但是没关系,通过对源码的观察,我们可以照猫画虎。
    先观察,为什么 post请求可以获取body里的参数。

    /**
     * Builds a route to match `POST` requests with specified [path] receiving request body content of type [R]
     */
    @ContextDsl
    @JvmName("postTyped")
    inline fun <reified R : Any> Route.post(
        path: String,
        crossinline body: suspend PipelineContext<Unit, ApplicationCall>.(R) -> Unit
    ): Route {
        return route(path, HttpMethod.Post) {
            handle {
                body(call.receive())
            }
        }
    }
    
    

    核心在于多了这个方法,多了这个带泛型的post方法。
    让我们对比下,只能获取url参数的get 方法

    typealias PipelineInterceptor<TSubject, TContext> = suspend PipelineContext<TSubject, TContext>.(TSubject) -> Unit
    
    /**
     * Builds a route to match `GET` requests with specified [path]
     */
    @ContextDsl
    fun Route.get(path: String, body: PipelineInterceptor<Unit, ApplicationCall>): Route {
        return route(path, HttpMethod.Get) { handle(body) }
    }
    

    对比之下,我们可以看到,最大的区别在于 handle(body) 和

    handle {
         body(call.receive())
    }
    

    这里,查阅源码,可知,call.receive() 会读取request 中body中的内容,此时我们的处理程序就可以 获取到body 中的内容了。需要注意的是,一个request, call.receive()只能执行一次,无法重复执行。
    最后补充代码如下

    
    @ContextDsl
    @JvmName("putTyped")
    inline fun <reified T : Any> Route.put(
        path: String,
        crossinline body: suspend PipelineContext<Unit, ApplicationCall>.(T) -> Unit
    ): Route {
        return route(path, HttpMethod.Put) {
            handle {
                body(call.receive())
            }
        }
    }
    
    @ContextDsl
    @JvmName("deleteTyped")
    inline fun <reified T : Any> Route.delete(
        path: String,
        crossinline body: suspend PipelineContext<Unit, ApplicationCall>.(T) -> Unit
    ): Route {
        return route(path, HttpMethod.Delete) {
            handle {
                body(call.receive())
            }
        }
    }
    

    需要注意两个 注解
    @ContextDsl 所注解的方法,在代码使用的地方,会被特殊高亮。
    @JvmName() 这是 用于在 编译为java 代码的时候,在java 代码中区分 同方法名,同参数名,但是泛型类型 不同的时候,用于指定方法名的 注解。

    相关文章

      网友评论

          本文标题:Ktor-开发实用技巧获(1)-获取put/delete请求bo

          本文链接:https://www.haomeiwen.com/subject/obixoctx.html