從 1.6.x 遷移到 2.0.x
本指南提供了將您的 Ktor 應用程式從 1.6.x 版遷移到 2.0.x 版的說明。
Ktor 伺服器
伺服器程式碼已移至 'io.ktor.server.*' 套件
為了統一並更好地區分伺服器和用戶端 API,伺服器程式碼已移至 io.ktor.server.*
套件 (KTOR-2865)。 這表示您需要更新應用程式中的 依賴項 和 匯入語句,如下所示。
依賴項
子系統 | 1.6.x | 2.0.0 |
---|---|---|
Locations | io.ktor:ktor-locations | io.ktor:ktor-server-locations |
Webjars | io.ktor:ktor-webjars | io.ktor:ktor-server-webjars |
AutoHeadResponse | io.ktor:ktor-server-core | io.ktor:ktor-server-auto-head-response |
StatusPages | io.ktor:ktor-server-core | io.ktor:ktor-server-status-pages |
CallId | io.ktor:ktor-server-core | io.ktor:ktor-server-call-id |
DoubleReceive | io.ktor:ktor-server-core | io.ktor:ktor-server-double-receive |
HTML DSL | io.ktor:ktor-html-builder | io.ktor:ktor-server-html-builder |
FreeMarker | io.ktor:ktor-freemarker | io.ktor:ktor-server-freemarker |
Velocity | io.ktor:ktor-velocity | io.ktor:ktor-server-velocity |
Mustache | io.ktor:ktor-mustache | io.ktor:ktor-server-mustache |
Thymeleaf | io.ktor:ktor-thymeleaf | io.ktor:ktor-server-thymeleaf |
Pebble | io.ktor:ktor-pebble | io.ktor:ktor-server-pebble |
kotlinx.serialization | io.ktor:ktor-serialization | io.ktor:ktor-server-content-negotiation , io.ktor:ktor-serialization-kotlinx-json |
Gson | io.ktor:ktor-gson | io.ktor:ktor-server-content-negotiation , io.ktor:ktor-serialization-gson |
Jackson | io.ktor:ktor-jackson | io.ktor:ktor-server-content-negotiation , io.ktor:ktor-serialization-jackson |
Authentication | io.ktor:ktor-auth | io.ktor:ktor-server-auth |
JWT authentication | io.ktor:ktor-auth-jwt | io.ktor:ktor-server-auth-jwt |
LDAP authentication | io.ktor:ktor-auth-ldap | io.ktor:ktor-server-auth-ldap |
DataConversion | io.ktor:ktor-server-core | io.ktor:ktor-server-data-conversion |
DefaultHeaders | io.ktor:ktor-server-core | io.ktor:ktor-server-default-headers |
Compression | io.ktor:ktor-server-core | io.ktor:ktor-server-compression |
CachingHeaders | io.ktor:ktor-server-core | io.ktor:ktor-server-caching-headers |
ConditionalHeaders | io.ktor:ktor-server-core | io.ktor:ktor-server-conditional-headers |
CORS | io.ktor:ktor-server-core | io.ktor:ktor-server-cors |
Forwarded headers | io.ktor:ktor-server-core | io.ktor:ktor-server-forwarded-header |
HSTS | io.ktor:ktor-server-core | io.ktor:ktor-server-hsts |
HttpsRedirect | io.ktor:ktor-server-core | io.ktor:ktor-server-http-redirect |
PartialContent | io.ktor:ktor-server-core | io.ktor:ktor-server-partial-content |
WebSockets | io.ktor:ktor-websockets | io.ktor:ktor-server-websockets |
CallLogging | io.ktor:ktor-server-core | io.ktor:ktor-server-call-logging |
Micrometer 指標 | io.ktor:ktor-metrics-micrometer | io.ktor:ktor-server-metrics-micrometer |
Dropwizard 指標 | io.ktor:ktor-metrics | io.ktor:ktor-server-metrics |
Sessions | io.ktor:ktor-server-core | io.ktor:ktor-server-sessions |
若要一次性新增所有外掛程式,您可以使用
io.ktor:ktor-server
構件。
匯入
子系統 | 1.6.x | 2.0.0 |
---|---|---|
Application | import io.ktor.application.* | import io.ktor.server.application.* |
組態 | import io.ktor.config.* | import io.ktor.server.config.* |
Routing | import io.ktor.routing.* | import io.ktor.server.routing.* |
AutoHeadResponse | import io.ktor.features.* | import io.ktor.server.plugins.autohead.* |
StatusPages | import io.ktor.features.* | import io.ktor.server.plugins.statuspages.* |
CallId | import io.ktor.features.* | import io.ktor.server.plugins.callid.* |
DoubleReceive | import io.ktor.features.* | import io.ktor.server.plugins.doublereceive.* |
請求 | import io.ktor.request.* | import io.ktor.server.request.* |
回應 | import io.ktor.response.* | import io.ktor.server.response.* |
外掛程式 | import io.ktor.features.* | import io.ktor.server.plugins.* |
Locations | import io.ktor.locations.* | import io.ktor.server.locations.* |
靜態內容 | import io.ktor.http.content.* | import io.ktor.server.http.content.* |
HTML DSL | import io.ktor.html.* | import io.ktor.server.html.* |
FreeMarker | import io.ktor.freemarker.* | import io.ktor.server.freemarker.* |
Velocity | import io.ktor.velocity.* | import io.ktor.server.velocity.* |
Mustache | import io.ktor.mustache.* | import io.ktor.server.mustache.* |
Thymeleaf | import io.ktor.thymeleaf.* | import io.ktor.server.thymeleaf.* |
Pebble | import io.ktor.pebble.* | import io.ktor.server.pebble.* |
內容協商 | import io.ktor.features.* | import io.ktor.server.plugins.contentnegotiation.* |
kotlinx.serialization | import io.ktor.serialization.* | import io.ktor.serialization.kotlinx.json.* |
Gson | import io.ktor.gson.* | import io.ktor.serialization.gson.* |
Jackson | import io.ktor.jackson.* | import io.ktor.serialization.jackson.* |
身份驗證 | import io.ktor.auth.* | import io.ktor.server.auth.* |
JWT 身份驗證 | import io.ktor.auth.jwt.* | import io.ktor.server.auth.jwt.* |
LDAP 身份驗證 | import io.ktor.auth.ldap.* | import io.ktor.server.auth.ldap.* |
Sessions | import io.ktor.sessions.* | import io.ktor.server.sessions.* |
DefaultHeaders | import io.ktor.features.* | import io.ktor.server.plugins.defaultheaders.* |
Compression | import io.ktor.features.* | import io.ktor.server.plugins.compression.* |
CachingHeaders | import io.ktor.features.* | import io.ktor.server.plugins.cachingheaders.* |
ConditionalHeaders | import io.ktor.features.* | import io.ktor.server.plugins.conditionalheaders.* |
CORS | import io.ktor.features.* | import io.ktor.server.plugins.cors.* |
轉發標頭 | import io.ktor.features.* | import io.ktor.server.plugins.forwardedheaders.* |
HSTS | import io.ktor.features.* | import io.ktor.server.plugins.hsts.* |
HttpsRedirect | import io.ktor.features.* | import io.ktor.server.plugins.httpsredirect.* |
PartialContent | import io.ktor.features.* | import io.ktor.server.plugins.partialcontent.* |
WebSockets | import io.ktor.websocket.* | import io.ktor.server.websocket.* |
CallLogging | import io.ktor.features.* | import io.ktor.server.plugins.callloging.* |
Micrometer 指標 | import io.ktor.metrics.micrometer.* | import io.ktor.server.metrics.micrometer.* |
Dropwizard 指標 | import io.ktor.metrics.dropwizard.* | import io.ktor.server.metrics.dropwizard.* |
WebSockets 程式碼已移至 'websockets' 套件
WebSockets 程式碼已從 http-cio
移至 websockets
套件。這需要如下更新匯入語句:
1.6.x | 2.0.0 |
---|---|
import io.ktor.http.cio.websocket.* | import io.ktor.websocket.* |
請注意,此變更也影響了 用戶端。
Feature 已更名為 Plugin
在 Ktor 2.0.0 中,Feature 已更名為 Plugin,以更好地描述攔截請求/回應管道的功能 (KTOR-2326)。 這影響了整個 Ktor API,需要按照以下說明更新您的應用程式。
匯入
安裝任何外掛程式 需要更新匯入語句,也取決於 伺服器程式碼的移動 到 io.ktor.server.*
套件:
1.6.x | 2.0.0 |
---|---|
import io.ktor.features.* | import io.ktor.server.plugins.* |
自訂外掛程式
將 Feature 更名為 Plugin 針對與 自訂外掛程式 相關的 API 引入了以下變更:
ApplicationFeature
介面已更名為BaseApplicationPlugin
。Features
管道階段 已更名為Plugins
。
請注意,從 v2.0.0 開始,Ktor 為 建立自訂外掛程式 提供了新的 API。一般而言,此 API 不需要理解 Ktor 內部概念,例如管道、階段等。取而代之的是,您可以使用各種處理程式(例如
onCall
、onCallReceive
、onCallRespond
等)來存取處理請求和回應的不同階段。您可以從本節了解管道階段如何映射到新 API 中的處理程式:管道階段到新 API 處理程式的映射。
內容協商與序列化
內容協商和序列化 伺服器 API 已經重構,以便重複利用伺服器和用戶端之間的序列化程式庫。 主要變更如下:
ContentNegotiation
已從ktor-server-core
移至單獨的ktor-server-content-negotiation
構件。- 序列化程式庫已從
ktor-*
移至ktor-serialization-*
構件,這些構件也由用戶端使用。
依賴項
子系統 | 1.6.x | 2.0.0 |
---|---|---|
ContentNegotiation | io.ktor:ktor-server-core | io.ktor:ktor-server-content-negotiation |
kotlinx.serialization | io.ktor:ktor-serialization | io.ktor:ktor-serialization-kotlinx-json |
Gson | io.ktor:ktor-gson | io.ktor:ktor-serialization-gson |
Jackson | io.ktor:ktor-jackson | io.ktor:ktor-serialization-jackson |
匯入
子系統 | 1.6.x | 2.0.0 |
---|---|---|
kotlinx.serialization | import io.ktor.serialization.* | import io.ktor.serialization.kotlinx.json.* |
Gson | import io.ktor.gson.* | import io.ktor.serialization.gson.* |
Jackson | import io.ktor.jackson.* | import io.ktor.serialization.jackson.* |
自訂轉換器
由 ContentConverter 介面公開的函式簽名已變更如下:
interface ContentConverter {
suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any?
suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any?
}
interface ContentConverter {
suspend fun serialize(contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any): OutgoingContent?
suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any?
}
測試 API
在 2.0.0 版中,Ktor 伺服器使用了新的 測試 API,它解決了 KTOR-971 中描述的各種問題。主要變更如下:
withTestApplication
/withApplication
函式已替換為新的testApplication
函式。- 在
testApplication
函式中,您需要使用現有的 Ktor 用戶端 實例向您的伺服器發出請求並驗證結果。 - 若要測試特定功能(例如 cookies 或 WebSockets),您需要建立一個新的用戶端實例並安裝對應的 外掛程式。
讓我們來看幾個將 1.6.x 測試遷移到 2.0.0 的範例:
基本伺服器測試
在以下測試中,handleRequest
函式已替換為 client.get
請求:
@Test
fun testRootLegacyApi() {
withTestApplication(Application::module) {
handleRequest(HttpMethod.Get, "/").apply {
assertEquals(HttpStatusCode.OK, response.status())
assertEquals("Hello, world!", response.content)
}
}
}
@Test
fun testRoot() = testApplication {
val response = client.get("/")
assertEquals(HttpStatusCode.OK, response.status)
assertEquals("Hello, world!", response.bodyAsText())
}
x-www-form-urlencoded
在以下測試中,handleRequest
函式已替換為 client.post
請求:
@Test
fun testPostLegacyApi() = withTestApplication(Application::main) {
with(handleRequest(HttpMethod.Post, "/signup"){
addHeader(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
setBody(listOf("username" to "JetBrains", "email" to "[email protected]", "password" to "foobar", "confirmation" to "foobar").formUrlEncode())
}) {
assertEquals("The 'JetBrains' account is created", response.content)
}
}
@Test
fun testPost() = testApplication {
val response = client.post("/signup") {
header(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
setBody(listOf("username" to "JetBrains", "email" to "[email protected]", "password" to "foobar", "confirmation" to "foobar").formUrlEncode())
}
assertEquals("The 'JetBrains' account is created", response.bodyAsText())
}
multipart/form-data
在 2.0.0 版中建構 multipart/form-data
,您需要將 MultiPartFormDataContent
傳遞給用戶端的 setBody
函式:
@Test
fun testUploadLegacyApi() = withTestApplication(Application::main) {
with(handleRequest(HttpMethod.Post, "/upload"){
val boundary = "WebAppBoundary"
val fileBytes = File("ktor_logo.png").readBytes()
addHeader(HttpHeaders.ContentType, ContentType.MultiPart.FormData.withParameter("boundary", boundary).toString())
setBody(boundary, listOf(
PartData.FormItem("Ktor logo", { }, headersOf(
HttpHeaders.ContentDisposition,
ContentDisposition.Inline
.withParameter(ContentDisposition.Parameters.Name, "description")
.toString()
)),
PartData.FileItem({ fileBytes.inputStream().asInput() }, {}, headersOf(
HttpHeaders.ContentDisposition,
ContentDisposition.File
.withParameter(ContentDisposition.Parameters.Name, "image")
.withParameter(ContentDisposition.Parameters.FileName, "ktor_logo.png")
.toString()
))
))
}) {
assertEquals("Ktor logo is uploaded to 'uploads/ktor_logo.png'", response.content)
}
}
@Test
fun testUpload() = testApplication {
val boundary = "WebAppBoundary"
val response = client.post("/upload") {
setBody(
MultiPartFormDataContent(
formData {
append("description", "Ktor logo")
append("image", File("ktor_logo.png").readBytes(), Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"ktor_logo.png\"")
})
},
boundary,
ContentType.MultiPart.FormData.withParameter("boundary", boundary)
)
)
}
assertEquals("Ktor logo is uploaded to 'uploads/ktor_logo.png'", response.bodyAsText())
}
JSON 資料
在 1.6.x 版中,您可以使用 kotlinx.serialization
程式庫提供的 Json.encodeToString
函式來序列化 JSON 資料。 在 2.0.0 版中,您需要建立一個新的用戶端實例並安裝 ContentNegotiation 外掛程式,該外掛程式允許以特定格式序列化/反序列化內容:
@Test
fun testPostCustomerLegacyApi() = withTestApplication(Application::main) {
with(handleRequest(HttpMethod.Post, "/customer"){
addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(Json.encodeToString(Customer(3, "Jet", "Brains")))
}) {
assertEquals("Customer stored correctly", response.content)
assertEquals(HttpStatusCode.Created, response.status())
}
}
@Test
fun testPostCustomer() = testApplication {
val client = createClient {
install(ContentNegotiation) {
json()
}
}
val response = client.post("/customer") {
contentType(ContentType.Application.Json)
setBody(Customer(3, "Jet", "Brains"))
}
assertEquals("Customer stored correctly", response.bodyAsText())
assertEquals(HttpStatusCode.Created, response.status)
}
在測試期間保留 cookies
在 1.6.x 版中,cookiesSession
用於在測試時保留請求之間的 cookies。在 2.0.0 版中,您需要建立一個新的用戶端實例並安裝 HttpCookies 外掛程式:
@Test
fun testRequestsLegacyApi() = withTestApplication(Application::main) {
fun doRequestAndCheckResponse(path: String, expected: String) {
handleRequest(HttpMethod.Get, path).apply {
assertEquals(expected, response.content)
}
}
cookiesSession {
handleRequest(HttpMethod.Get, "/login") {}.apply {}
doRequestAndCheckResponse("/user", "Session ID is 123abc. Reload count is 0.")
doRequestAndCheckResponse("/user", "Session ID is 123abc. Reload count is 1.")
doRequestAndCheckResponse("/user", "Session ID is 123abc. Reload count is 2.")
handleRequest(HttpMethod.Get, "/logout").apply {}
doRequestAndCheckResponse("/user", "Session doesn't exist or is expired.")
}
}
@Test
fun testRequests() = testApplication {
val client = createClient {
install(HttpCookies)
}
val loginResponse = client.get("/login")
val response1 = client.get("/user")
assertEquals("Session ID is 123abc. Reload count is 1.", response1.bodyAsText())
val response2 = client.get("/user")
assertEquals("Session ID is 123abc. Reload count is 2.", response2.bodyAsText())
val response3 = client.get("/user")
assertEquals("Session ID is 123abc. Reload count is 3.", response3.bodyAsText())
val logoutResponse = client.get("/logout")
assertEquals("Session doesn't exist or is expired.", logoutResponse.bodyAsText())
}
WebSockets
在舊 API 中,handleWebSocketConversation
用於測試 WebSocket 對話。在 2.0.0 版中,您可以透過使用用戶端提供的 WebSockets 外掛程式來測試 WebSocket 對話:
@Test
fun testConversationLegacyApi() {
withTestApplication(Application::module) {
handleWebSocketConversation("/echo") { incoming, outgoing ->
val greetingText = (incoming.receive() as Frame.Text).readText()
assertEquals("Please enter your name", greetingText)
outgoing.send(Frame.Text("JetBrains"))
val responseText = (incoming.receive() as Frame.Text).readText()
assertEquals("Hi, JetBrains!", responseText)
}
}
}
@Test
fun testConversation() {
testApplication {
val client = createClient {
install(WebSockets)
}
client.webSocket("/echo") {
val greetingText = (incoming.receive() as? Frame.Text)?.readText() ?: ""
assertEquals("Please enter your name", greetingText)
send(Frame.Text("JetBrains"))
val responseText = (incoming.receive() as Frame.Text).readText()
assertEquals("Hi, JetBrains!", responseText)
}
}
}
DoubleReceive
在 2.0.0 版中,DoubleReceive 外掛程式組態引入了 cacheRawRequest
屬性,這與 receiveEntireContent
相反:
- 在 1.6.x 版中,
receiveEntireContent
屬性預設為false
。 - 在 2.0.0 版中,
cacheRawRequest
預設為true
。receiveEntireContent
屬性已移除。
轉發標頭
在 2.0.0 版中,ForwardedHeaderSupport
和 XForwardedHeaderSupport
外掛程式已分別更名為 ForwardedHeaders 和 XForwardedHeaders
。
快取標頭
用於定義快取選項的 options 函式現在除了 OutgoingContent
之外,還接受 ApplicationCall
作為 lambda 參數:
install(CachingHeaders) {
options { outgoingContent ->
// ...
}
}
install(CachingHeaders) {
options { call, outgoingContent ->
// ...
}
}
條件式標頭
用於定義資源版本清單的 version 函式現在除了 OutgoingContent
之外,還接受 ApplicationCall
作為 lambda 參數:
install(ConditionalHeaders) {
version { outgoingContent ->
// ...
}
}
install(ConditionalHeaders) {
version { call, outgoingContent ->
// ...
}
}
CORS
CORS 組態中使用的幾個函式已更名:
host
->allowHost
header
->allowHeader
method
->allowMethod
install(CORS) {
host("0.0.0.0:5000")
header(HttpHeaders.ContentType)
method(HttpMethod.Options)
}
install(CORS) {
allowHost("0.0.0.0:5000")
allowHeader(HttpHeaders.ContentType)
allowMethod(HttpMethod.Options)
}
MicrometerMetrics
在 1.6.x 版中,baseName
屬性用於指定用於監控 HTTP 請求的 Ktor 指標 的基本名稱(前綴)。 預設情況下,它等於 ktor.http.server
。 在 2.0.0 版中,baseName
已替換為 metricName
,其預設值為 ktor.http.server.requests
。
Ktor 用戶端
請求與回應
在 2.0.0 版中,用於發出請求和接收回應的 API 已更新,使其更一致且更易於發現 (KTOR-29)。
請求函式
具有多個參數的 請求函式 已棄用。例如,port
和 path
參數需要替換為由 HttpRequestBuilder 公開的 url
參數:
client.get(port = 8080, path = "/customer/3")
client.get { url(port = 8080, path = "/customer/3") }
HttpRequestBuilder
還允許您在請求函式 lambda 內部指定額外的 請求參數。
請求主體
用於設定 請求主體 的 HttpRequestBuilder.body
屬性已替換為 HttpRequestBuilder.setBody
函式:
client.post("http://localhost:8080/post") {
body = "Body content"
}
client.post("http://localhost:8080/post") {
setBody("Body content")
}
回應
在 2.0.0 版中,請求函式(例如 get
、post
、put
、submitForm 等)不再接受用於接收特定類型物件的泛型參數。 現在所有請求函式都返回一個 HttpResponse
物件,該物件公開了帶有泛型參數的 body
函式,用於接收特定類型實例。 您也可以使用 bodyAsText
或 bodyAsChannel
以字串或通道的形式接收內容。
val httpResponse: HttpResponse = client.get("https://ktor.io/")
val stringBody: String = httpResponse.receive()
val byteArrayBody: ByteArray = httpResponse.receive()
val httpResponse: HttpResponse = client.get("https://ktor.io/")
val stringBody: String = httpResponse.body()
val byteArrayBody: ByteArray = httpResponse.body()
安裝了 ContentNegotiation 外掛程式後,您可以如下接收任意物件:
val customer: Customer = client.get("http://localhost:8080/customer/3")
val customer: Customer = client.get("http://localhost:8080/customer/3").body()
串流回應
由於從請求函式中 移除泛型參數,接收串流回應需要單獨的函式。 為此,添加了帶有 prepare
字首的函式,例如 prepareGet
或 preparePost
:
public suspend fun HttpClient.prepareGet(builder: HttpRequestBuilder): HttpStatement
public suspend fun HttpClient.preparePost(builder: HttpRequestBuilder): HttpStatement
以下範例說明了在這種情況下如何變更您的程式碼:
client.get<HttpStatement>("https://ktor.io/").execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
while (!channel.isClosedForRead) {
// Read data
}
}
client.prepareGet("https://ktor.io/").execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.body()
while (!channel.isClosedForRead) {
// Read data
}
}
您可以在此處找到完整範例:串流資料。
回應驗證
在 2.0.0 版中,用於 回應驗證 的 expectSuccess
屬性預設為 false
。 這需要在您的程式碼中進行以下變更:
- 若要 啟用預設驗證 並對非 2xx 回應拋出異常,請將
expectSuccess
屬性設定為true
。 - 如果您使用
handleResponseExceptionWithRequest
處理非 2xx 異常,您也需要明確啟用expectSuccess
。
HttpResponseValidator
handleResponseException 函式已替換為 handleResponseExceptionWithRequest
,它增加了對 HttpRequest
的存取,以在異常中提供額外資訊:
HttpResponseValidator {
handleResponseException { exception ->
// ...
}
}
HttpResponseValidator {
handleResponseExceptionWithRequest { exception, request ->
// ...
}
}
內容協商與序列化
Ktor 用戶端現在支援內容協商,並與 Ktor 伺服器共用序列化程式庫。 主要變更如下:
JsonFeature
已棄用,取而代之的是ContentNegotiation
,該內容可在ktor-client-content-negotiation
構件中找到。- 序列化程式庫已從
ktor-client-*
移至ktor-serialization-*
構件。
您需要更新用戶端程式碼中的 依賴項 和 匯入語句,如下所示。
依賴項
子系統 | 1.6.x | 2.0.0 |
---|---|---|
ContentNegotiation | n/a | io.ktor:ktor-client-content-negotiation |
kotlinx.serialization | io.ktor:ktor-client-serialization | io.ktor:ktor-serialization-kotlinx-json |
Gson | io.ktor:ktor-client-gson | io.ktor:ktor-serialization-gson |
Jackson | io.ktor:ktor-client-jackson | io.ktor:ktor-serialization-jackson |
匯入
子系統 | 1.6.x | 2.0.0 |
---|---|---|
ContentNegotiation | n/a | import io.ktor.client.plugins.contentnegotiation.* |
kotlinx.serialization | import io.ktor.client.features.json.* | import io.ktor.serialization.kotlinx.json.* |
Gson | import io.ktor.client.features.json.* | import io.ktor.serialization.gson.* |
Jackson | import io.ktor.client.features.json.* | import io.ktor.serialization.jackson.* |
Bearer 身份驗證
refreshTokens 函式現在使用 RefreshTokenParams
實例作為 lambda 接收器 (this
),而不是 HttpResponse
lambda 參數 (it
):
bearer {
refreshTokens { // it: HttpResponse
// ...
}
}
bearer {
refreshTokens { // this: RefreshTokenParams
// ...
}
}
RefreshTokenParams
公開了以下屬性:
response
,用於存取回應參數;client
,用於發出刷新權杖的請求;oldTokens
,用於存取使用loadTokens
取得的權杖。
HttpSend
HttpSend 外掛程式的 API 變更如下:
client[HttpSend].intercept { originalCall, request ->
if (originalCall.something()) {
val newCall = execute(request)
// ...
}
}
client.plugin(HttpSend).intercept { request ->
val originalCall = execute(request)
if (originalCall.something()) {
val newCall = execute(request)
// ...
}
}
請注意,在 2.0.0 版中,索引存取不適用於存取外掛程式。請改用 HttpClient.plugin 函式。
HttpClient.get(plugin: HttpClientPlugin) 函式已移除
在 2.0.0 版中,接受用戶端外掛程式的 HttpClient.get
函式已移除。請改用 HttpClient.plugin
函式。
client.get(HttpSend).intercept { ... }
// or
client[HttpSend].intercept { ... }
client.plugin(HttpSend).intercept { ... }
Feature 已更名為 Plugin
如同 Ktor 伺服器,Feature 在用戶端 API 中已更名為 Plugin。 這可能會影響您的應用程式,如下所述。
匯入
更新 安裝外掛程式 的匯入語句:
子系統 | 1.6.x | 2.0.0 |
| import io.ktor.client.features.* | import io.ktor.client.plugins.* |
身份驗證 The Auth plugin handles authentication and authorization in your client application. | import io.ktor.client.features.auth.* import io.ktor.client.features.auth.providers.* | import io.ktor.client.plugins.auth.* import io.ktor.client.plugins.auth.providers.* |
Cookies The HttpCookies plugin handles cookies automatically and keep them between calls in a storage. | import io.ktor.client.features.cookies.* | import io.ktor.client.plugins.cookies.* |
記錄 Required dependencies: io.ktor:ktor-client-logging Code example: %example_name% | import io.ktor.client.features.logging.* | import io.ktor.client.plugins.logging.* |
WebSockets The Websockets plugin allows you to create a multi-way communication session between a server and a client. | import io.ktor.client.features.websocket.* | import io.ktor.client.plugins.websocket.* |
內容編碼 The ContentEncoding plugin allows you to enable specified compression algorithms (such as 'gzip' and 'deflate') and configure their settings. | import io.ktor.client.features.compression.* | import io.ktor.client.plugins.compression.* |
自訂外掛程式
HttpClientFeature
介面已更名為 HttpClientPlugin
。
Native 目標的新記憶體模型
在 2.0.0 版中,在 Native 目標上使用 Ktor 用戶端需要啟用新的 Kotlin/Native 記憶體模型:啟用新的記憶體模型。
從 2.2.0 版開始,新的 Kotlin/Native 記憶體模型 預設啟用。
「Ios」引擎已更名為「Darwin」
鑑於 Ios 引擎 不僅針對 iOS,還針對包括 macOS 或 tvOS 在內的其他作業系統,在 2.0.0 版中,它已更名為 Darwin
。這導致以下變更:
io.ktor:ktor-client-ios
構件已更名為io.ktor:ktor-client-darwin
。- 若要建立
HttpClient
實例,您需要傳遞Darwin
類別作為參數。 IosClientEngineConfig
組態類別已更名為DarwinClientEngineConfig
。
若要了解如何組態 Darwin
引擎,請參閱 Darwin 一節。
WebSockets 程式碼已移至「websockets」套件
WebSockets 程式碼已從 http-cio
移至 websockets
套件。這需要如下更新匯入語句:
1.6.x | 2.0.0 |
---|---|
import io.ktor.http.cio.websocket.* | import io.ktor.websocket.* |
預設請求
DefaultRequest 外掛程式使用 DefaultRequestBuilder
組態類別,而不是 HttpRequestBuilder
:
val client = HttpClient(CIO) {
defaultRequest {
// this: HttpRequestBuilder
}
}
val client = HttpClient(CIO) {
defaultRequest {
// this: DefaultRequestBuilder
}
}