Skip to content
Client Plugin

Ktor Client 中的内容协商与序列化

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

代码示例 client-json-kotlinx

ContentNegotiation 插件有两个主要用途:

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

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

添加依赖项

ContentNegotiation

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

Kotlin
Groovy
XML

TIP

要了解更多关于 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 提供的序列化设置,例如:

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

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