Kotlin 原语的 Spring 验证
Posted
技术标签:
【中文标题】Kotlin 原语的 Spring 验证【英文标题】:Spring validation for Kotlin primitives 【发布时间】:2021-01-18 02:41:21 【问题描述】:我使用 Kotlin 1.4.10 创建了 simple Spring Boot project。
我在项目中有简单的 DTO:
data class TestRequest(
@field:NotNull val id: Int,
val optionalId: Int?,
val name: String,
val optionalName: String?,
@field:NotNull val value: Double,
val optionalValue: Double?,
val nested: NestedRequest,
val optionalNested: NestedRequest?
)
data class NestedRequest(
@field:NotNull val nestedId: Long,
val nestedOptionalId: Long?,
val nestedName: String,
val optionalNestedName: String?
)
我想知道,编写 Kotlin DTO 并验证它们的最佳实践是什么?
一方面,Kotlin 允许将字段标记为非空,这似乎便于验证。 从另一个角度来看,对于 Kotlin 数字类型(Int、Long、Double 等),它似乎具有默认值,就像 Java 原语一样,因此检查可空性不适用于与字符串不同的字段。如果我使用@JsonProperty(required = true),Jackson 会检查可空性而不是验证器,所以这种方法也是不正确的。
因此,我有一个问题 - 有没有一种验证 Kotlin DTO 的正确方法?
【问题讨论】:
【参考方案1】:正如您所注意到的,很难验证 kotlin 原始类型的可空性,因为它们具有默认值。
我会说结合使用 Jackson(用于原始类型的可空性)和 Javax 验证(诸如最小值/最大值之类的东西)很好。
但是,如果您不想使用 Jackson 验证,则可以通过将变量的类型设置为可为空但将其注释为 @NotNull 来验证原始类型。
例如:
import javax.validation.Valid
import javax.validation.constraints.NotNull
data class MyClass(
@get:Valid
@get:NotNull
val someInt: Int?,
val someText: String
)
现在,因为类型可以为空(在本例中为 Int?
),Jackson 不会为 someInt
插入默认值,因此 someInt
将具有 null
的值。之后,当对象被验证时,会抛出错误,因为someInt
的值为空。
例如,如果我们有以下@PostMapping
:
@PostMapping("/test")
fun testFunction(@RequestBody @Valid data: MyClass)
print(data)
发送带有正文的 POST 请求:
"someText": "wow"
会返回类似这样的错误:
"timestamp": "2020-10-02T15:22:53.361+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void main.api.TestPublicController.myObject(main.api.MyClass): [Field error in object 'myClass' on field 'someInt': rejected value [null]; ...
【讨论】:
以上是关于Kotlin 原语的 Spring 验证的主要内容,如果未能解决你的问题,请参考以下文章
android RecyclerView pinch zoom,ScaleGestureDetector&GridLayoutManager,with BigImageViewer,kotli