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