Ktor公开了一些扩展方法,用于解析和生成url编码的字符串(以application/x-www-form-urlencoded
mimetype格式).
URL编码的字符串看起来像: param=value&other=hi
.
有一个String
扩展方法,允许您从中获取已解析的Parameters
对象. 您可以使用可选的limit
参数limit
解析参数的最大数量.
fun String.parseUrlEncodedParameters(defaultEncoding: Charset = Charsets.UTF_8, limit: Int = 1000): Parameters
您可以从"字符串对列表"或" Parameters
实例生成URL编码的字符串:
fun List<Pair<String, String?>>.formUrlEncode(): String
fun List<Pair<String, String?>>.formUrlEncodeTo(out: Appendable)
fun Parameters.formUrlEncode(): String
fun Parameters.formUrlEncodeTo(out: Appendable)
您可以从List<Pair<String, String>>
构造URL编码的字符串List<Pair<String, String>>
如下所示:
listOf(
"error" to "invalid_request",
"error_description" to "client_id is missing"
).formUrlEncode()
您还可以从可以实例化的Parameters
实例中构造它,方法是使用Parameters.build
构建器,然后调用formUrlEncode
扩展,或使用parametersOf()
构建器方法:
Parameters.build {
append("error", "invalid_request")
append("error_description", "client_id is missing")
}.formUrlEncode()
parametersOf
构建器具有多个签名,并且存在用于合并两个Parameters
实例的Parameters
运算符重载( +
):
parametersOf("a" to "b1", "a" to "b2").formUrlEncode()
(parametersOf("a", "b1") + parametersOf("a", "b2")).formUrlEncode()
parametersOf("a", listOf("b1", "b2")).formUrlEncode()
您还可以从普通的Map<String, String>
构造一个URL编码的字符串,但是首先必须从中创建一个List:
mapOf(
"error" to "invalid_request",
"error_description" to "client_id is missing"
).toList().formUrlEncode()
URL编码的字符串使您可以重复输入密钥. 如果使用Map<String, String>
作为基础,则将无法表示重复的键. 在这种情况下,请考虑使用parametersOf
, List
或Parameters.build
.
您还可以通过首先将其Map<String, List<String>>
到Map<String, List<String>>
来构造它:
mapOf(
"error" to listOf("invalid_request"),
"error_descriptions" to listOf("client_id is missing", "server error")
).flatMap { map -> map.value.map { map.key to it } }.formUrlEncode()
如果要避免使用内容构造整个String而是想直接写到某个地方,可以使用formUrlEncodeTo
方法.
您可以执行以下操作:
call.respondUrlEncoded("hello" to listOf("world"))
通过向项目添加以下扩展方法:
suspend fun ApplicationCall.respondUrlEncoded(vararg keys: Pair<String, List<String>>) =
respondUrlEncoded(parametersOf(*keys))
suspend fun ApplicationCall.respondUrlEncoded(parameters: Parameters) =
respondTextWriter(ContentType.Application.FormUrlEncoded) {
parameters.formUrlEncodeTo(this)
}