Ktor Client 中的内容协商与序列化
所需依赖项:io.ktor:ktor-client-content-negotiation
代码示例: client-json-kotlinx
ContentNegotiation 插件有两个主要用途:
- 在客户端与服务器之间协商媒体类型。为此,它使用
Accept和Content-Type标头。 - 在发送 请求 和接收 响应 时以特定格式序列化/反序列化内容。Ktor 开箱即用支持以下格式:JSON、XML、CBOR 和 ProtoBuf。
在服务器端,Ktor 提供了 ContentNegotiation 插件用于序列化/反序列化内容。
添加依赖项
ContentNegotiation
要使用 ContentNegotiation,您需要在构建脚本中包含 ktor-client-content-negotiation 构件:
TIP
要了解更多关于 Ktor 客户端所需构件的信息,请参阅请注意,特定格式的序列化器需要额外的构件。例如,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 提供的序列化设置,例如:
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.jackson.*
import com.fasterxml.jackson.databind.*
import java.text.DateFormat
val client = HttpClient(CIO) {
install(ContentNegotiation) {
jackson {
enable(SerializationFeature.INDENT_OUTPUT)
dateFormat = DateFormat.getDateInstance()
}
}
}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。
