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 构件:

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 插件,则可以验证对象属性。通过 示例:验证对象属性 了解更多信息。

  • 第二个 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. 为了验证接收到的数据,我们将使用接受 ValidatorBuilder 且允许您提供自定义验证规则的第二个 validate 函数重载
    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
            }
        }
    }