Utilities exposed by Ktor (URL-Encoding)

预计阅读时间:2分钟

Handling URL-encoded properties

Ktor公开了一些扩展方法,用于解析和生成url编码的字符串(以application/x-www-form-urlencoded mimetype格式).

URL编码的字符串看起来像: param=value&other=hi .

Parsing:

有一个String扩展方法,允许您从中获取已解析的Parameters对象. 您可以使用可选的limit参数limit解析参数的最大数量.

fun String.parseUrlEncodedParameters(defaultEncoding: Charset = Charsets.UTF_8, limit: Int = 1000): Parameters

Encoding:

您可以从"字符串对列表"或" 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>作为基础,则将无法表示重复的键. 在这种情况下,请考虑使用parametersOfListParameters.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方法.

Responding URL-encoded

您可以执行以下操作:

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)
    }

by  ICOPY.SITE