Ktor Client 中的內容協商與序列化
所需的相依性:io.ktor:ktor-client-content-negotiation
程式碼範例: client-json-kotlinx
ContentNegotiation 外掛程式有兩個主要用途:
- 在用戶端與伺服器之間協商媒體類型。為此,它會使用
Accept和Content-Type標頭。 - 在傳送 請求 (requests) 和接收 回應 (responses) 時,以特定格式序列化/反序列化內容。Ktor 開箱即用支援以下格式:JSON、XML、CBOR 和 ProtoBuf。
在伺服器上,Ktor 提供了 ContentNegotiation 外掛程式用於序列化/反序列化內容。
新增相依性
ContentNegotiation
要使用 ContentNegotiation,您需要在組建指令碼中包含 ktor-client-content-negotiation 構件:
TIP
您可以從請注意,特定格式的序列化程式需要額外的構件。例如,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:
請注意,
jsNode目標 不支援 XML 序列化。
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 程式庫支援以下類型的序列化/反序列化:
- 內建類別
- 序列 (Sequences) 的反序列化
- 流程 (Flows) 的序列化
傳送資料
要將 類別執行個體 作為 JSON 在 請求 (request) 內容中傳送,請使用 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 的 回應 (response) 時,您可以透過指定 資料類別 作為用於接收回應有效負載之函式的參數(在下方範例中為 body)來將其反序列化:
val customer: Customer = client.get("http://localhost:8080/customer/3").body()您可以在這裡找到完整的範例:client-json-kotlinx。
