Ktor-server RequestValidation 不起作用



我正在使用ktor(2.1.0)创建一个小型API。在这样做的同时,我正在尝试利用Ktor-server很酷的功能,包括RequestValidation。

话虽如此,它不起作用,我无法弄清楚为什么,因为在我看来它非常接近文档中的示例。

这是我的服务器配置:

embeddedServer(Netty, port = 8080) {
routing {
post("/stock") {
val dto = call.receive<CreateStockRequest>()
call.respond(HttpStatusCode.NoContent)
}
}
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
})
}
install(StatusPages) {
exception<RequestValidationException> { call, cause ->
call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
}
}
install(RequestValidation) {
validate<CreateStockRequest> { request ->
if (request.name.isBlank())
ValidationResult.Invalid("Stock must have a name")
if (request.symbol.isBlank())
ValidationResult.Invalid("Symbol must have a name")
ValidationResult.Valid
}
}
}

这是正在"接收"的请求对象:

@Serializable
data class CreateStockRequest(val name: String, val symbol: String)

这是正在发送的身体:

{
"name": "",
"symbol": "something"
}

我本以为会得到BadRequest的回复,但我得到了NoContent的回应,好像这个请求一切都很好。

我做错了什么吗?

在您的示例中,仅当"name"和"symbol"均为空时,服务器才会响应BadRequest。您可以将验证逻辑替换为when表达式:

validate<CreateStockRequest> { request ->
when {
request.name.isBlank() -> ValidationResult.Invalid("Stock must have a name")
request.symbol.isBlank() -> ValidationResult.Invalid("Symbol must have a name")
else -> ValidationResult.Valid
}
}

我发现接受的答案是一个更干净的代码解决方案,这就是为什么它是公认的答案。

话虽如此,通过理解编译器与作用域混淆,可以更好地解释我遇到的实际问题。 在每个"if"子句上,我需要返回验证结果,但编译器没有它。

其原因是它与我的返回声明所指的背景混淆了。 我的解决方案是使用"@"表示法来指定返回的范围:

validate<CreateStockRequest> { request ->
if (request.name.isBlank())
return@validate ValidationResult.Invalid("Stock must have a name")
if (request.symbol.isBlank())
return@validate ValidationResult.Invalid("Symbol must have a name")
return@validate ValidationResult.Valid
}
}

相关内容

  • 没有找到相关文章

最新更新