Ktor 客户端中的内容协商与序列化
必需的依赖项: io.ktor:ktor-client-content-negotiation
代码示例: client-json-kotlinx
ContentNegotiation 插件主要服务于两个目的:
- 在客户端和服务器之间协商媒体类型。为此,它使用
Accept
和Content-Type
头部。 - 在发送请求和接收响应时以特定格式序列化/反序列化内容。Ktor 开箱即用支持以下格式:JSON、XML、CBOR 和 ProtoBuf。请注意,XML 序列化器仅支持 JVM。
在服务器端,Ktor 提供 ContentNegotiation 插件用于序列化/反序列化内容。
添加依赖项
ContentNegotiation
要使用 ContentNegotiation
,你需要在构建脚本中包含 ktor-client-content-negotiation
构件:
你可以从
请注意,特定格式的序列化器需要额外的构件。例如,kotlinx.serialization 需要 ktor-serialization-kotlinx-json
依赖项用于 JSON。根据包含的构件,Ktor 会自动选择一个默认序列化器。如果需要,你可以显式指定序列化器并对其进行配置。
序列化
在使用 kotlinx.serialization 转换器之前,你需要按照 Setup 小节中的说明添加 Kotlin 序列化插件。
JSON
要序列化/反序列化 JSON 数据,你可以选择以下库之一:kotlinx.serialization、Gson 或 Jackson。
在构建脚本中添加 ktor-serialization-kotlinx-json
构件:
在构建脚本中添加 ktor-serialization-gson
构件:
在构建脚本中添加 ktor-serialization-jackson
构件:
XML
要序列化/反序列化 XML,请在构建脚本中添加 ktor-serialization-kotlinx-xml
:
请注意,XML 序列化在
jsNode
目标上不受支持。
CBOR
要序列化/反序列化 CBOR,请在构建脚本中添加 ktor-serialization-kotlinx-cbor
:
ProtoBuf
要序列化/反序列化 ProtoBuf,请在构建脚本中添加 ktor-serialization-kotlinx-protobuf
:
安装 ContentNegotiation
要安装 ContentNegotiation
,请在客户端配置块内将其传递给 install
函数:
val client = HttpClient(CIO) {
install(ContentNegotiation)
}
现在你可以配置所需的 JSON 序列化器。
配置序列化器
JSON 序列化器
要在你的应用程序中注册 JSON 序列化器,请调用 json
方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json()
}
}
在 json
构造函数中,你可以访问 JsonBuilder API,例如:
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
})
}
}
你可以在此处找到完整示例:client-json-kotlinx。
要在你的应用程序中注册 Gson 序列化器,请调用 gson 方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.gson.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
gson()
}
}
gson
方法还允许你调整由 GsonBuilder 提供的序列化设置。
要在你的应用程序中注册 Jackson 序列化器,请调用 jackson 方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.jackson.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
jackson()
}
}
jackson
方法还允许你调整由 ObjectMapper 提供的序列化设置。
XML 序列化器
要在你的应用程序中注册 XML 序列化器,请调用 xml
方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.xml.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
xml()
}
}
xml
方法还允许你访问 XML 序列化设置,例如:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.xml.*
import nl.adaptivity.xmlutil.*
import nl.adaptivity.xmlutil.serialization.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
xml(format = XML {
xmlDeclMode = XmlDeclMode.Charset
})
}
}
CBOR 序列化器
要在你的应用程序中注册 CBOR 序列化器,请调用 cbor
方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.cbor.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
cbor()
}
}
cbor
方法还允许你访问由 CborBuilder 提供的 CBOR 序列化设置,例如:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.cbor.*
import kotlinx.serialization.cbor.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
cbor(Cbor {
ignoreUnknownKeys = true
})
}
}
ProtoBuf 序列化器
要在你的应用程序中注册 ProtoBuf 序列化器,请调用 protobuf
方法:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.protobuf.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
protobuf()
}
}
protobuf
方法还允许你访问由 ProtoBufBuilder 提供的 ProtoBuf 序列化设置,例如:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.protobuf.*
import kotlinx.serialization.protobuf.*
val client = HttpClient(CIO) {
install(ContentNegotiation) {
protobuf(ProtoBuf {
encodeDefaults = true
})
}
}
接收和发送数据
创建数据类
要接收和发送数据,你需要有一个数据类,例如:
data class Customer(val id: Int, val firstName: String, val lastName: String)
如果你使用 kotlinx.serialization,请确保此类别带有 @Serializable
注解:
@Serializable
data class Customer(val id: Int, val firstName: String, val lastName: String)
kotlinx.serialization 库支持以下类型的序列化/反序列化:
发送数据
要在 请求 体中以 JSON 形式发送类实例,请使用 setBody
函数赋值此实例,并通过调用 contentType
将内容类型设置为 application/json
:
val response: HttpResponse = client.post("http://localhost:8080/customer") {
contentType(ContentType.Application.Json)
setBody(Customer(3, "Jet", "Brains"))
}
要以 XML 或 CBOR 形式发送数据,请分别将 contentType
设置为 ContentType.Application.Xml
或 ContentType.Application.Cbor
。
接收数据
当服务器发送带有 application/json
、application/xml
或 application/cbor
内容的响应时,你可以通过将数据类指定为用于接收响应负载的函数的形参(以下示例中的 body
)来反序列化它:
val customer: Customer = client.get("http://localhost:8080/customer/3").body()
你可以在此处找到完整示例:client-json-kotlinx。