Kotlin需要NotNull吗?

时间:2017-02-02 03:29:18

标签: spring-mvc kotlin bean-validation

我有一个班级:

class User(

    var name: String

)

一个映射的帖子请求:

@PostMapping("/user")
fun test(@Valid @RequestBody user: User) {
    //...
}

如果客户端使用name: null发送用户的JSON,该怎么办?是否会被MVC Validator拒绝或抛出异常?我应该使用name注释@NotNull吗?不幸的是,我无法检查,因为只能编写测试(无法创建User(null))。

4 个答案:

答案 0 :(得分:5)

由于nameUser的非空参数,因此无法接受null s。

保证Kotlin编译器:

  • null构造函数中插入User检查,如果某些Java代码试图传递null,则会抛出异常。

  • 使用name注释@NotNull以便与Java API保持一致

  • 不添加任何@NotNull注释,因为没有人都同意:(

以下是相应的docs

更新

我已经重新检查了它,Kotlin编译器v1.0.6 @Nullable插入@NotNullorg.jetbrains.annotations。我已相应更新了答案。

答案 1 :(得分:5)

你可以避免使用@NotNull,因为它永远不会被非可空属性触发(bean验证只有在杰克逊反序列化JSON之后才会启动 - 这就是失败的地方)。

假设您正在使用jackson-module-kotlin,那么您应该以MissingKotlinParameterException作为根本原因获得例外,然后您可以在@ControllerAdvice中处理该例外。在您的建议中,您可以处理正常的bean验证异常(例如ConstraintViolationException引起的@Size)和缺少非空构造函数参数(MissingKotlinParameterException)并返回指示错误字段的API响应。

唯一需要注意的是jackson-kotlin-module fails on the first missing property与Java中的bean验证不同,它将返回所有违规行为。

答案 2 :(得分:0)

在我测试时,@NotNull根本不影响MVC验证。您只会在控制台中收到WARN消息,这是正常的:

  

无法读取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableException:无法读取文档:实例化...

答案 3 :(得分:0)

我现在的工作环境(将文件放置在任何地方):

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
class ExceptionHandler {

    @ResponseStatus(BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler(MissingKotlinParameterException::class)
    fun missingKotlinParameterException(ex: MissingKotlinParameterException): Error? {
        return createMissingKotlinParameterViolation(ex)
    }

    private fun createMissingKotlinParameterViolation(ex: MissingKotlinParameterException): Error{
        val error = Error(BAD_REQUEST.value(), "validation error")
        val errorFieldRegex = Regex("\\.([^.]*)\\[\\\"(.*)\"\\]\$")
        val errorMatch = errorFieldRegex.find(ex.path[0].description)!!
        val (objectName, field) = errorMatch.destructured
        error.addFieldError(objectName.decapitalize(), field, "must not be null")
        return error
    }

    data class Error(val status: Int, val message: String, val fieldErrors: MutableList<CustomFieldError> = mutableListOf()) {
        fun addFieldError(objectName: String, field: String, message: String) {
            val error = CustomFieldError(objectName, field, message)
            fieldErrors.add(error)
        }
    }

    data class CustomFieldError(val objectName: String, val field: String, val message: String)