Ktor-开发实用技巧获(1)-获取put/delete请求body中的参数

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  Route.post(
    path: String,
    crossinline body: suspend PipelineContext.(R) -> Unit
): Route {
    return route(path, HttpMethod.Post) {
        handle {
            body(call.receive())
        }
    }
}

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

typealias PipelineInterceptor = suspend PipelineContext.(TSubject) -> Unit

/**
 * Builds a route to match `GET` requests with specified [path]
 */
@ContextDsl
fun Route.get(path: String, body: PipelineInterceptor): 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  Route.put(
    path: String,
    crossinline body: suspend PipelineContext.(T) -> Unit
): Route {
    return route(path, HttpMethod.Put) {
        handle {
            body(call.receive())
        }
    }
}

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

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

你可能感兴趣的:(Ktor-开发实用技巧获(1)-获取put/delete请求body中的参数)