Skip to content
Server Plugin

请求验证

所需依赖项: io.ktor:ktor-server-request-validation

代码示例: request-validation

原生服务器
Ktor 支持 Kotlin/Native,允许你在没有额外运行时或虚拟机的情况下运行服务器。
支持: ✅

RequestValidation 插件提供了验证传入请求体的功能。如果安装了带有序列化器ContentNegotiation 插件,你可以验证原始请求体或指定的请求对象属性。如果请求体验证失败,该插件会抛出 RequestValidationException 异常,可以使用 StatusPages 插件来处理。

添加依赖项

要使用 RequestValidation,你需要在构建脚本中引入 ktor-server-request-validation artifact:

Kotlin
Groovy
XML

安装 RequestValidation

要将 RequestValidation 插件安装到应用程序, 请将其传递给指定

模块
模块允许你通过对路由进行分组来组织你的应用程序。
中的 install 函数。 下面的代码片段展示了如何安装 RequestValidation ...

  • ... 在 embeddedServer 函数调用内部。
  • ... 在显式定义的 module 内部,它是 Application 类的扩展函数。
kotlin
kotlin

RequestValidation 插件也可以安装到特定的路由。 如果你需要针对不同的应用程序资源使用不同的 RequestValidation 配置,这可能会很有用。

配置 RequestValidation

配置 RequestValidation 涉及三个主要步骤:

  1. 接收请求体内容
  2. 配置验证函数
  3. 处理验证异常

1. 接收请求体

RequestValidation插件会在你使用类型参数调用 **[receive](server-requests.md#body_contents)** 函数时验证请求体。例如,下面的代码片段展示了如何以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 插件,你可以验证对象属性。从示例:验证对象属性了解更多。

  • 第二个 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
            }
        }
    }