Skip to content
Server Plugin

請求驗證

必要相依性io.ktor:ktor-server-request-validation

程式碼範例 request-validation

Native 伺服器
Ktor 支援 Kotlin/Native,允許你在不使用額外執行階段或虛擬機的情況下執行伺服器。
支援:✅

RequestValidation 外掛程式提供了驗證傳入請求主體的能力。如果安裝了包含 序列化程式 (serializer)ContentNegotiation 外掛程式,你可以驗證原始請求主體或指定的請求物件屬性。如果請求主體驗證失敗,該外掛程式會拋出 RequestValidationException,可以使用 StatusPages 外掛程式來處理。

新增相依性

若要使用 RequestValidation,你需要在建置指令碼中包含 ktor-server-request-validation 構件:

Kotlin
Groovy
XML

安裝 RequestValidation

若要在應用程式中安裝 RequestValidation 外掛程式,請將其傳遞給指定

模組
模組允許你透過分組路由來組織應用程式。
中的 install 函式。 下方的程式碼片段展示了如何安裝 RequestValidation ...

  • ... 在 embeddedServer 函式呼叫內部。
  • ... 在明確定義的 module 內部,該模組是 Application 類別的擴充函式。
kotlin
kotlin

RequestValidation 外掛程式也可以安裝到特定路由。 如果你需要為不同的應用程式資源使用不同的 RequestValidation 配置,這會非常有用。

設定 RequestValidation

設定 RequestValidation 包含三個主要步驟:

  1. 接收主體內容
  2. 設定驗證函式
  3. 處理驗證例外

1. 接收主體

如果你呼叫帶有型別參數的 receive 函式,RequestValidation 外掛程式會驗證請求的主體。例如,下方的程式碼片段展示了如何將主體作為 String 值接收:

kotlin
routing {
    post("/text") {
        val body = call.receive<String>()
        call.respond(body)
    }
}

2. 設定驗證函式

若要驗證請求主體,請使用 validate 函式。 此函式會傳回一個 ValidationResult 物件,代表驗證成功或失敗的結果。 對於失敗的結果,會拋出 RequestValidationException

validate 函式有兩個多載,允許你以兩種方式驗證請求主體:

  • 第一個 validate 多載允許你將請求主體作為指定型別的物件來存取。 下方的範例展示了如何驗證代表 String 值的請求主體:

    kotlin
    install(RequestValidation) {
        validate<String> { bodyText ->
            if (!bodyText.startsWith("Hello"))
                ValidationResult.Invalid("Body text should start with 'Hello'")
            else ValidationResult.Valid
        }
    }

    如果你安裝了 ContentNegotiation 外掛程式並配置了特定的 序列化程式 (serializer),你可以驗證物件屬性。請從 範例:驗證物件屬性 了解更多資訊。

  • 第二個 validate 多載接受 ValidatorBuilder 並允許你提供自訂驗證規則。 你可以從 範例:驗證位元組陣列 了解更多資訊。

3. 處理驗證例外

如果請求驗證失敗,RequestValidation 會拋出 RequestValidationException。 此例外允許你存取請求主體,並獲取此請求所有驗證失敗的原因。

你可以使用 StatusPages 外掛程式來處理 RequestValidationException,如下所示:

kotlin
install(StatusPages) {
    exception<RequestValidationException> { call, cause ->
        call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
    }
}

你可以在這裡找到完整範例:request-validation

範例:驗證物件屬性

在此範例中,我們將查看如何使用 RequestValidation 外掛程式驗證物件屬性。 假設伺服器接收到一個包含以下 JSON 資料的 POST 請求:

HTTP
POST http://0.0.0.0:8080/json
Content-Type: application/json

{
  "id": -1,
  "firstName": "Jet",
  "lastName": "Brains"
}

若要新增 id 屬性的驗證,請按照以下步驟操作:

  1. 建立描述上述 JSON 物件的 Customer 資料類別:

    kotlin
    @Serializable
    data class Customer(val id: Int, val firstName: String, val lastName: String)
  2. 安裝帶有 JSON 序列化程式ContentNegotiation 外掛程式:

    kotlin
    install(ContentNegotiation) {
        json()
    }
  3. 在伺服器端接收 Customer 物件,如下所示:

    kotlin
    post("/json") {
        val customer = call.receive<Customer>()
        call.respond(customer)
    }
  4. RequestValidation 外掛程式配置中,新增 id 屬性的驗證,以確保其位於指定的範圍內:

    kotlin
    install(RequestValidation) {
        validate<Customer> { customer ->
            if (customer.id <= 0)
                ValidationResult.Invalid("A customer ID should be greater than 0")
            else ValidationResult.Valid
        }
    }

    在這種情況下,如果 id 值小於或等於 0RequestValidation 將會拋出 RequestValidationException

範例:驗證位元組陣列

在此範例中,我們將查看如何驗證以位元組陣列形式接收的請求主體。 假設伺服器接收到一個包含以下文字資料的 POST 請求:

HTTP
POST http://localhost:8080/array
Content-Type: text/plain

-1

若要以位元組陣列形式接收資料並進行驗證,請執行以下步驟:

  1. 在伺服器端接收資料,如下所示:
    kotlin
    post("/array") {
        val body = call.receive<ByteArray>()
        call.respond(String(body))
    }
  2. 若要驗證接收到的資料,我們將使用第二個 validate 函式多載,它接受 ValidatorBuilder 並允許你提供自訂驗證規則:
    kotlin
    install(RequestValidation) {
        validate {
            filter { body ->
                body is ByteArray
            }
            validation { body ->
                check(body is ByteArray)
                val intValue = String(body).toInt()
                if (intValue <= 0)
                    ValidationResult.Invalid("A value should be greater than 0")
                else ValidationResult.Valid
            }
        }
    }