Skip to content
Client Plugin

Ktor 客户端中的内容协商与序列化

必需的依赖项: io.ktor:ktor-client-content-negotiation

代码示例: client-json-kotlinx

ContentNegotiation 插件主要服务于两个目的:

  • 在客户端和服务器之间协商媒体类型。为此,它使用 AcceptContent-Type 头部。
  • 在发送请求和接收响应时以特定格式序列化/反序列化内容。Ktor 开箱即用支持以下格式:JSON、XML、CBOR 和 ProtoBuf。请注意,XML 序列化器仅支持 JVM

在服务器端,Ktor 提供 ContentNegotiation 插件用于序列化/反序列化内容。

添加依赖项

ContentNegotiation

要使用 ContentNegotiation,你需要在构建脚本中包含 ktor-client-content-negotiation 构件:

Kotlin
Groovy
XML

你可以从

添加客户端依赖项
了解如何向现有项目添加客户端依赖项。
中了解更多关于 Ktor 客户端所需的构件。

请注意,特定格式的序列化器需要额外的构件。例如,kotlinx.serialization 需要 ktor-serialization-kotlinx-json 依赖项用于 JSON。根据包含的构件,Ktor 会自动选择一个默认序列化器。如果需要,你可以显式指定序列化器并对其进行配置。

序列化

在使用 kotlinx.serialization 转换器之前,你需要按照 Setup 小节中的说明添加 Kotlin 序列化插件。

JSON

要序列化/反序列化 JSON 数据,你可以选择以下库之一:kotlinx.serialization、Gson 或 Jackson。

在构建脚本中添加 ktor-serialization-kotlinx-json 构件:

Kotlin
Groovy
XML

在构建脚本中添加 ktor-serialization-gson 构件:

Kotlin
Groovy
XML

在构建脚本中添加 ktor-serialization-jackson 构件:

Kotlin
Groovy
XML

XML

要序列化/反序列化 XML,请在构建脚本中添加 ktor-serialization-kotlinx-xml

Kotlin
Groovy
XML

请注意,XML 序列化jsNode 目标上不受支持

CBOR

要序列化/反序列化 CBOR,请在构建脚本中添加 ktor-serialization-kotlinx-cbor

Kotlin
Groovy
XML

ProtoBuf

要序列化/反序列化 ProtoBuf,请在构建脚本中添加 ktor-serialization-kotlinx-protobuf

Kotlin
Groovy
XML

安装 ContentNegotiation

要安装 ContentNegotiation,请在客户端配置块内将其传递给 install 函数:

kotlin
val client = HttpClient(CIO) {
    install(ContentNegotiation)
}

现在你可以配置所需的 JSON 序列化器。

配置序列化器

JSON 序列化器

要在你的应用程序中注册 JSON 序列化器,请调用 json 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        json()
    }
}

json 构造函数中,你可以访问 JsonBuilder API,例如:

kotlin
val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        json(Json {
            prettyPrint = true
            isLenient = true
        })
    }
}

你可以在此处找到完整示例:client-json-kotlinx

要在你的应用程序中注册 Gson 序列化器,请调用 gson 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.gson.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        gson()
    }
}

gson 方法还允许你调整由 GsonBuilder 提供的序列化设置。

要在你的应用程序中注册 Jackson 序列化器,请调用 jackson 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.jackson.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        jackson()
    }
}

jackson 方法还允许你调整由 ObjectMapper 提供的序列化设置。

XML 序列化器

要在你的应用程序中注册 XML 序列化器,请调用 xml 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.xml.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        xml()
    }
}

xml 方法还允许你访问 XML 序列化设置,例如:

kotlin
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 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.cbor.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        cbor()
    }
}

cbor 方法还允许你访问由 CborBuilder 提供的 CBOR 序列化设置,例如:

kotlin
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 方法:

kotlin
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.protobuf.*

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
        protobuf()
    }
}

protobuf 方法还允许你访问由 ProtoBufBuilder 提供的 ProtoBuf 序列化设置,例如:

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

接收和发送数据

创建数据类

要接收和发送数据,你需要有一个数据类,例如:

kotlin
data class Customer(val id: Int, val firstName: String, val lastName: String)

如果你使用 kotlinx.serialization,请确保此类别带有 @Serializable 注解:

kotlin
@Serializable
data class Customer(val id: Int, val firstName: String, val lastName: String)

kotlinx.serialization 库支持以下类型的序列化/反序列化:

发送数据

要在 请求 体中以 JSON 形式发送类实例,请使用 setBody 函数赋值此实例,并通过调用 contentType 将内容类型设置为 application/json

kotlin
val response: HttpResponse = client.post("http://localhost:8080/customer") {
    contentType(ContentType.Application.Json)
    setBody(Customer(3, "Jet", "Brains"))
}

要以 XML 或 CBOR 形式发送数据,请分别将 contentType 设置为 ContentType.Application.XmlContentType.Application.Cbor

接收数据

当服务器发送带有 application/jsonapplication/xmlapplication/cbor 内容的响应时,你可以通过将数据类指定为用于接收响应负载的函数的形参(以下示例中的 body)来反序列化它:

kotlin
val customer: Customer = client.get("http://localhost:8080/customer/3").body()

你可以在此处找到完整示例:client-json-kotlinx