Skip to content

從 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.x2.0.0
Locationsio.ktor:ktor-locationsio.ktor:ktor-server-locations
Webjarsio.ktor:ktor-webjarsio.ktor:ktor-server-webjars
AutoHeadResponseio.ktor:ktor-server-coreio.ktor:ktor-server-auto-head-response
StatusPagesio.ktor:ktor-server-coreio.ktor:ktor-server-status-pages
CallIdio.ktor:ktor-server-coreio.ktor:ktor-server-call-id
DoubleReceiveio.ktor:ktor-server-coreio.ktor:ktor-server-double-receive
HTML DSLio.ktor:ktor-html-builderio.ktor:ktor-server-html-builder
FreeMarkerio.ktor:ktor-freemarkerio.ktor:ktor-server-freemarker
Velocityio.ktor:ktor-velocityio.ktor:ktor-server-velocity
Mustacheio.ktor:ktor-mustacheio.ktor:ktor-server-mustache
Thymeleafio.ktor:ktor-thymeleafio.ktor:ktor-server-thymeleaf
Pebbleio.ktor:ktor-pebbleio.ktor:ktor-server-pebble
kotlinx.serializationio.ktor:ktor-serializationio.ktor:ktor-server-content-negotiation, io.ktor:ktor-serialization-kotlinx-json
Gsonio.ktor:ktor-gsonio.ktor:ktor-server-content-negotiation, io.ktor:ktor-serialization-gson
Jacksonio.ktor:ktor-jacksonio.ktor:ktor-server-content-negotiation, io.ktor:ktor-serialization-jackson
Authenticationio.ktor:ktor-authio.ktor:ktor-server-auth
JWT authenticationio.ktor:ktor-auth-jwtio.ktor:ktor-server-auth-jwt
LDAP authenticationio.ktor:ktor-auth-ldapio.ktor:ktor-server-auth-ldap
DataConversionio.ktor:ktor-server-coreio.ktor:ktor-server-data-conversion
DefaultHeadersio.ktor:ktor-server-coreio.ktor:ktor-server-default-headers
Compressionio.ktor:ktor-server-coreio.ktor:ktor-server-compression
CachingHeadersio.ktor:ktor-server-coreio.ktor:ktor-server-caching-headers
ConditionalHeadersio.ktor:ktor-server-coreio.ktor:ktor-server-conditional-headers
CORSio.ktor:ktor-server-coreio.ktor:ktor-server-cors
Forwarded headersio.ktor:ktor-server-coreio.ktor:ktor-server-forwarded-header
HSTSio.ktor:ktor-server-coreio.ktor:ktor-server-hsts
HttpsRedirectio.ktor:ktor-server-coreio.ktor:ktor-server-http-redirect
PartialContentio.ktor:ktor-server-coreio.ktor:ktor-server-partial-content
WebSocketsio.ktor:ktor-websocketsio.ktor:ktor-server-websockets
CallLoggingio.ktor:ktor-server-coreio.ktor:ktor-server-call-logging
Micrometer 指標io.ktor:ktor-metrics-micrometerio.ktor:ktor-server-metrics-micrometer
Dropwizard 指標io.ktor:ktor-metricsio.ktor:ktor-server-metrics
Sessionsio.ktor:ktor-server-coreio.ktor:ktor-server-sessions

若要一次性新增所有外掛程式,您可以使用 io.ktor:ktor-server 構件。

匯入

子系統1.6.x2.0.0
Applicationimport io.ktor.application.*import io.ktor.server.application.*
組態import io.ktor.config.*import io.ktor.server.config.*
Routingimport io.ktor.routing.*import io.ktor.server.routing.*
AutoHeadResponseimport io.ktor.features.*import io.ktor.server.plugins.autohead.*
StatusPagesimport io.ktor.features.*import io.ktor.server.plugins.statuspages.*
CallIdimport io.ktor.features.*import io.ktor.server.plugins.callid.*
DoubleReceiveimport 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.*
Locationsimport io.ktor.locations.*import io.ktor.server.locations.*
靜態內容import io.ktor.http.content.*import io.ktor.server.http.content.*
HTML DSLimport io.ktor.html.*import io.ktor.server.html.*
FreeMarkerimport io.ktor.freemarker.*import io.ktor.server.freemarker.*
Velocityimport io.ktor.velocity.*import io.ktor.server.velocity.*
Mustacheimport io.ktor.mustache.*import io.ktor.server.mustache.*
Thymeleafimport io.ktor.thymeleaf.*import io.ktor.server.thymeleaf.*
Pebbleimport io.ktor.pebble.*import io.ktor.server.pebble.*
內容協商import io.ktor.features.*import io.ktor.server.plugins.contentnegotiation.*
kotlinx.serializationimport io.ktor.serialization.*import io.ktor.serialization.kotlinx.json.*
Gsonimport io.ktor.gson.*import io.ktor.serialization.gson.*
Jacksonimport 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.*
Sessionsimport io.ktor.sessions.*import io.ktor.server.sessions.*
DefaultHeadersimport io.ktor.features.*import io.ktor.server.plugins.defaultheaders.*
Compressionimport io.ktor.features.*import io.ktor.server.plugins.compression.*
CachingHeadersimport io.ktor.features.*import io.ktor.server.plugins.cachingheaders.*
ConditionalHeadersimport io.ktor.features.*import io.ktor.server.plugins.conditionalheaders.*
CORSimport io.ktor.features.*import io.ktor.server.plugins.cors.*
轉發標頭import io.ktor.features.*import io.ktor.server.plugins.forwardedheaders.*
HSTSimport io.ktor.features.*import io.ktor.server.plugins.hsts.*
HttpsRedirectimport io.ktor.features.*import io.ktor.server.plugins.httpsredirect.*
PartialContentimport io.ktor.features.*import io.ktor.server.plugins.partialcontent.*
WebSocketsimport io.ktor.websocket.*import io.ktor.server.websocket.*
CallLoggingimport 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.x2.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.x2.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 內部概念,例如管道、階段等。取而代之的是,您可以使用各種處理程式(例如 onCallonCallReceiveonCallRespond 等)來存取處理請求和回應的不同階段。您可以從本節了解管道階段如何映射到新 API 中的處理程式:管道階段到新 API 處理程式的映射

內容協商與序列化

內容協商和序列化 伺服器 API 已經重構,以便重複利用伺服器和用戶端之間的序列化程式庫。 主要變更如下:

  • ContentNegotiation 已從 ktor-server-core 移至單獨的 ktor-server-content-negotiation 構件。
  • 序列化程式庫已從 ktor-* 移至 ktor-serialization-* 構件,這些構件也由用戶端使用。

您需要更新應用程式中的 依賴項匯入語句,如下所示。

依賴項

子系統1.6.x2.0.0
ContentNegotiationio.ktor:ktor-server-coreio.ktor:ktor-server-content-negotiation
kotlinx.serializationio.ktor:ktor-serializationio.ktor:ktor-serialization-kotlinx-json
Gsonio.ktor:ktor-gsonio.ktor:ktor-serialization-gson
Jacksonio.ktor:ktor-jacksonio.ktor:ktor-serialization-jackson

匯入

子系統1.6.x2.0.0
kotlinx.serializationimport io.ktor.serialization.*import io.ktor.serialization.kotlinx.json.*
Gsonimport io.ktor.gson.*import io.ktor.serialization.gson.*
Jacksonimport io.ktor.jackson.*import io.ktor.serialization.jackson.*

自訂轉換器

ContentConverter 介面公開的函式簽名已變更如下:

kotlin
interface ContentConverter {
    suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any?
    suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any?
}
kotlin
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 請求:

kotlin
@Test
fun testRootLegacyApi() {
    withTestApplication(Application::module) {
        handleRequest(HttpMethod.Get, "/").apply {
            assertEquals(HttpStatusCode.OK, response.status())
            assertEquals("Hello, world!", response.content)
        }
    }
}
kotlin
@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 請求:

kotlin
@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)
    }
}
kotlin
@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 函式:

kotlin
    @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)
        }
    }
kotlin
@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 外掛程式,該外掛程式允許以特定格式序列化/反序列化內容:

kotlin
@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())
    }
}
kotlin
@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 外掛程式:

kotlin
    @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.")
        }
    }
kotlin
    @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 對話:

kotlin
    @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)
            }
        }
    }
kotlin
    @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 預設為 truereceiveEntireContent 屬性已移除。

轉發標頭

在 2.0.0 版中,ForwardedHeaderSupportXForwardedHeaderSupport 外掛程式已分別更名為 ForwardedHeadersXForwardedHeaders

快取標頭

用於定義快取選項的 options 函式現在除了 OutgoingContent 之外,還接受 ApplicationCall 作為 lambda 參數:

kotlin
install(CachingHeaders) {
    options { outgoingContent ->
        // ...
    }
}
kotlin
install(CachingHeaders) {
    options { call, outgoingContent ->
        // ...
    }
}

條件式標頭

用於定義資源版本清單的 version 函式現在除了 OutgoingContent 之外,還接受 ApplicationCall 作為 lambda 參數:

kotlin
install(ConditionalHeaders) {
    version { outgoingContent ->
        // ... 
    }
}
kotlin
install(ConditionalHeaders) {
    version { call, outgoingContent ->
        // ... 
    }
}

CORS

CORS 組態中使用的幾個函式已更名:

  • host -> allowHost
  • header -> allowHeader
  • method -> allowMethod
kotlin
install(CORS) {
    host("0.0.0.0:5000")
    header(HttpHeaders.ContentType)
    method(HttpMethod.Options)
}
kotlin
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)。

請求函式

具有多個參數的 請求函式 已棄用。例如,portpath 參數需要替換為由 HttpRequestBuilder 公開的 url 參數:

kotlin
client.get(port = 8080, path = "/customer/3")
kotlin
client.get { url(port = 8080, path = "/customer/3") }

HttpRequestBuilder 還允許您在請求函式 lambda 內部指定額外的 請求參數

請求主體

用於設定 請求主體HttpRequestBuilder.body 屬性已替換為 HttpRequestBuilder.setBody 函式:

kotlin
client.post("http://localhost:8080/post") {
    body = "Body content"
}
kotlin
client.post("http://localhost:8080/post") {
    setBody("Body content")
}

回應

在 2.0.0 版中,請求函式(例如 getpostputsubmitForm 等)不再接受用於接收特定類型物件的泛型參數。 現在所有請求函式都返回一個 HttpResponse 物件,該物件公開了帶有泛型參數的 body 函式,用於接收特定類型實例。 您也可以使用 bodyAsTextbodyAsChannel 以字串或通道的形式接收內容。

kotlin
val httpResponse: HttpResponse = client.get("https://ktor.io/")
val stringBody: String = httpResponse.receive()
val byteArrayBody: ByteArray = httpResponse.receive()
kotlin
val httpResponse: HttpResponse = client.get("https://ktor.io/")
val stringBody: String = httpResponse.body()
val byteArrayBody: ByteArray = httpResponse.body()

安裝了 ContentNegotiation 外掛程式後,您可以如下接收任意物件:

kotlin
val customer: Customer = client.get("http://localhost:8080/customer/3")
kotlin
val customer: Customer = client.get("http://localhost:8080/customer/3").body()

串流回應

由於從請求函式中 移除泛型參數,接收串流回應需要單獨的函式。 為此,添加了帶有 prepare 字首的函式,例如 prepareGetpreparePost

kotlin
public suspend fun HttpClient.prepareGet(builder: HttpRequestBuilder): HttpStatement
public suspend fun HttpClient.preparePost(builder: HttpRequestBuilder): HttpStatement

以下範例說明了在這種情況下如何變更您的程式碼:

kotlin
client.get<HttpStatement>("https://ktor.io/").execute { httpResponse ->
    val channel: ByteReadChannel = httpResponse.receive()
    while (!channel.isClosedForRead) {
        // Read data
    }
}
kotlin
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 的存取,以在異常中提供額外資訊:

kotlin
HttpResponseValidator {
    handleResponseException { exception ->
        // ...
    }
}
kotlin
HttpResponseValidator {
    handleResponseExceptionWithRequest { exception, request ->
        // ...
    }
}

內容協商與序列化

Ktor 用戶端現在支援內容協商,並與 Ktor 伺服器共用序列化程式庫。 主要變更如下:

  • JsonFeature 已棄用,取而代之的是 ContentNegotiation,該內容可在 ktor-client-content-negotiation 構件中找到。
  • 序列化程式庫已從 ktor-client-* 移至 ktor-serialization-* 構件。

您需要更新用戶端程式碼中的 依賴項匯入語句,如下所示。

依賴項

子系統1.6.x2.0.0
ContentNegotiationn/aio.ktor:ktor-client-content-negotiation
kotlinx.serializationio.ktor:ktor-client-serializationio.ktor:ktor-serialization-kotlinx-json
Gsonio.ktor:ktor-client-gsonio.ktor:ktor-serialization-gson
Jacksonio.ktor:ktor-client-jacksonio.ktor:ktor-serialization-jackson

匯入

子系統1.6.x2.0.0
ContentNegotiationn/aimport io.ktor.client.plugins.contentnegotiation.*
kotlinx.serializationimport io.ktor.client.features.json.*import io.ktor.serialization.kotlinx.json.*
Gsonimport io.ktor.client.features.json.*import io.ktor.serialization.gson.*
Jacksonimport io.ktor.client.features.json.*import io.ktor.serialization.jackson.*

Bearer 身份驗證

refreshTokens 函式現在使用 RefreshTokenParams 實例作為 lambda 接收器 (this),而不是 HttpResponse lambda 參數 (it):

kotlin
bearer {
    refreshTokens {  // it: HttpResponse
        // ...
    }
}
kotlin
bearer {
    refreshTokens { // this: RefreshTokenParams
        // ...
    }
}

RefreshTokenParams 公開了以下屬性:

  • response,用於存取回應參數;
  • client,用於發出刷新權杖的請求;
  • oldTokens,用於存取使用 loadTokens 取得的權杖。

HttpSend

HttpSend 外掛程式的 API 變更如下:

kotlin
client[HttpSend].intercept { originalCall, request ->
    if (originalCall.something()) {
        val newCall = execute(request)
        // ...
    }
}
kotlin
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 函式。

kotlin
client.get(HttpSend).intercept { ... }
// or
client[HttpSend].intercept { ... }
kotlin
client.plugin(HttpSend).intercept { ... }

Feature 已更名為 Plugin

如同 Ktor 伺服器,Feature 在用戶端 API 中已更名為 Plugin。 這可能會影響您的應用程式,如下所述。

匯入

更新 安裝外掛程式 的匯入語句:

子系統1.6.x2.0.0
  • 預設請求
    The DefaultRequest plugin allows you to configure default parameters for all requests.
  • 字元集
    undefined
  • 回應驗證
    Learn how to validate a response depending on its status code.
  • 逾時
    Code example: %example_name%
  • HttpCache
    The HttpCache plugin allows you to save previously fetched resources in an in-memory or persistent cache.
  • HttpSend
    Code example: %example_name%
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.x2.0.0
import io.ktor.http.cio.websocket.*import io.ktor.websocket.*

預設請求

DefaultRequest 外掛程式使用 DefaultRequestBuilder 組態類別,而不是 HttpRequestBuilder

kotlin
val client = HttpClient(CIO) {
    defaultRequest {
        // this: HttpRequestBuilder
    }
}
kotlin
val client = HttpClient(CIO) {
    defaultRequest {
        // this: DefaultRequestBuilder
    }
}