【问题标题】:Kotlin data class and Bean validation: @NotNull on Long fields does not workKotlin 数据类和 Bean 验证:长字段上的 @NotNull 不起作用
【发布时间】:2018-09-28 12:46:06
【问题描述】:

这是数据类:

data class CreateCommentRequest(
        @field:NotNull
        @field:NotEmpty
        val comment: String,

        @field:NotNull
        val postId: Long
)

如果我省略了comment 字段,验证会正常失败。

但是如果我不通过postId,像这样:

{
    "comment": "hello"
}

验证通过。

如果postId没有通过,如何使验证失败?

附:我使用带有com.fasterxml.jackson.module:jackson-module-kotlin 模块的spring boot 2.0.1,kotlin 版本:1.2.20

【问题讨论】:

    标签: validation spring-boot kotlin


    【解决方案1】:

    我认为这与https://github.com/FasterXML/jackson-module-kotlin/issues/130有关。

    看起来你可以打开DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES,但这不会导致验证错误,但会导致构造对象失败。您需要适当地处理该异常以生成 400 错误。

    如果你真的想要验证,你需要允许构造对象,这样验证器才能运行,这意味着使原始字段可以为空:

    data class CreateCommentRequest(
        @field:NotNull
        @field:NotEmpty
        val comment: String,
    
        @field:NotNull
        val postId: Long?
    )
    

    这可能看起来违反直觉,但验证器在对象构建之前不会运行。它不是杰克逊(它不关心验证注释)或 kotlin 的一部分。除非您提供了替代实现,否则 Hibernate 验证器会根据注释进行 null 检查,并且它需要一个完整的对象才能执行此检查。

    看起来 jackson kotlin 模块正在创建对象的实例,但它必须为 postId 提供一个值,因此它提供了一个默认值 0(除非您指示它在 null 原语上失败)。

    import com.fasterxml.jackson.databind.ObjectMapper
    import com.fasterxml.jackson.module.kotlin.KotlinModule
    
    data class Test(val x : Long)
    
    fun main(args : Array<String>) {
        val m = ObjectMapper().registerModule(KotlinModule())
        print(m.readValue("{}", Test::class.java)) // prints Test(x=0) 
    }
    

    通过使该字段可以为空,您可以构造它,以便 JSR 303 验证可以在对象上运行。

    【讨论】:

    • 实际上使非空值可以为空仅用于验证是一个非常肮脏的解决方案。有修复了吗?
    猜你喜欢
    • 2022-01-09
    • 2014-09-23
    • 2016-06-21
    • 2014-08-30
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多