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 需要用於 JSON 的 ktor-serialization-kotlinx-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