请求验证
所需依赖项: io.ktor:ktor-server-request-validation
代码示例: request-validation
RequestValidation 插件提供了验证传入请求体的功能。如果安装了带有序列化器的 ContentNegotiation
插件,你可以验证原始请求体或指定的请求对象属性。如果请求体验证失败,该插件会抛出 RequestValidationException
异常,可以使用 StatusPages 插件来处理。
添加依赖项
要使用 RequestValidation
,你需要在构建脚本中引入 ktor-server-request-validation
artifact:
安装 RequestValidation
要将 RequestValidation
插件安装到应用程序, 请将其传递给指定
install
函数。 下面的代码片段展示了如何安装 RequestValidation
... - ... 在
embeddedServer
函数调用内部。 - ... 在显式定义的
module
内部,它是Application
类的扩展函数。
RequestValidation
插件也可以安装到特定的路由。 如果你需要针对不同的应用程序资源使用不同的 RequestValidation
配置,这可能会很有用。
配置 RequestValidation
配置 RequestValidation
涉及三个主要步骤:
1. 接收请求体
RequestValidation插件会在你使用类型参数调用 **[receive](server-requests.md#body_contents)** 函数时验证请求体。例如,下面的代码片段展示了如何以
String 值接收请求体:
routing {
post("/text") {
val body = call.receive<String>()
call.respond(body)
}
}
2. 配置验证函数
要验证请求体,请使用 validate
函数。 此函数返回一个 ValidationResult
对象,表示成功或不成功的验证结果。 对于不成功的结果,会抛出 RequestValidationException 异常。
validate
函数有两个重载,允许你通过两种方式验证请求体:
第一个
validate
重载允许你将请求体作为指定类型的对象进行访问。 下面的示例展示了如何验证表示String
值的请求体:kotlininstall(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
异常,如下所示:
install(StatusPages) {
exception<RequestValidationException> { call, cause ->
call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
}
}
你可以在这里找到完整示例:request-validation。
示例:验证对象属性
在此示例中,我们将探讨如何使用 RequestValidation
插件验证对象属性。 假设服务器接收到一个带有以下 JSON 数据的 POST
请求:
POST http://0.0.0.0:8080/json
Content-Type: application/json
{
"id": -1,
"firstName": "Jet",
"lastName": "Brains"
}
要添加 id
属性的验证,请按照以下步骤操作:
创建描述上述 JSON 对象的
Customer
数据类:kotlin@Serializable data class Customer(val id: Int, val firstName: String, val lastName: String)
安装带有 JSON 序列化器 的
ContentNegotiation
插件:kotlininstall(ContentNegotiation) { json() }
在服务器端接收
Customer
对象,如下所示:kotlinpost("/json") { val customer = call.receive<Customer>() call.respond(customer) }
在
RequestValidation
插件配置中,添加id
属性的验证,以确保其落在指定区间内:kotlininstall(RequestValidation) { validate<Customer> { customer -> if (customer.id <= 0) ValidationResult.Invalid("A customer ID should be greater than 0") else ValidationResult.Valid } }
在这种情况下,如果
id
值小于或等于0
,RequestValidation
将会抛出 RequestValidationException 异常。
示例:验证字节数组
在此示例中,我们将探讨如何验证作为字节数组接收到的请求体。 假设服务器接收到一个带有以下文本数据的 POST
请求:
POST http://localhost:8080/array
Content-Type: text/plain
-1
要将数据作为字节数组接收并验证它,请执行以下步骤:
- 在服务器端接收数据,如下所示:kotlin
post("/array") { val body = call.receive<ByteArray>() call.respond(String(body)) }
- 要验证接收到的数据,我们将使用第二个
validate
函数重载,它接受ValidatorBuilder
并允许你提供自定义的验证规则:kotlininstall(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 } } }