Spring not null验证在kotlin中抛出HttpMessageNotReadableException而不是MethodArgumentNotValidException

时间:2019-02-21 00:07:41

标签: spring rest validation kotlin

我正在使用Spring在Kotlin中进行简单的应用程序制作,但我在验证方面遇到了问题。

我有这个实体类:

@Entity
@Table(name = "category")
data class Category(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long?,
        @field:NotNull @field:NotEmpty val name: String)

我的控制器功能如下:

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun create(@Valid @RequestBody category: Category): ResponseEntity<Category>

create有一些代码,但是与问题无关,我的问题是请求正文验证。如果我发送的类别的名称字段为空,则会引发MethodArgumentNotValidException异常,但是如果我将null发送到字段name,则会引发异常HttpMessageNotReadableException。有没有人知道是否可以将null传递给标有@NotNull的字段,并将MethodArgumentNotValidException也扔到Kotlin中。

2 个答案:

答案 0 :(得分:0)

因此,您的问题是将name字段指定为不可为空,默认情况下,kotlin的杰克逊模块将对其进行检查,并抛出json映射过程中由HttpMessageNotReadableException引起的MissingKotlinParameterException。如果您将name标记为可空的json映射将通过并通过@Valid进入Spring验证阶段,那么我们将获得MethodArgumentNotValidException

@Entity
@Table(name = "category")
data class Category(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long?,
    @field:NotNull @field:NotEmpty val name: String?)

答案 1 :(得分:0)

您可以通过提供HttpMessageNotReadableException处理程序来解决此问题 然后检查根本原因是否为MissingKotlinParameterException

之后,您可以提供自定义验证错误。我使用的是zalando-problem,因此语法与普通弹簧有些不同,但是您可以理解:

    @ExceptionHandler
    override fun handleMessageNotReadableException(
        exception: HttpMessageNotReadableException,
        request: NativeWebRequest
    ): ResponseEntity<Problem> {
        // workaround
        val cause = exception.cause
        if (cause is MissingKotlinParameterException) {
            val violations = setOf(createMissingKotlinParameterViolation(cause))
            return newConstraintViolationProblem(exception, violations, request)
        }
        return create(Status.BAD_REQUEST, UnableToReadInputMessageProblem(), request)
    }

    private fun createMissingKotlinParameterViolation(cause: MissingKotlinParameterException): Violation {
        val name = cause.path.fold("") { jsonPath, ref ->
            val suffix = when {
                ref.index > -1 -> "[${ref.index}]"
                else -> ".${ref.fieldName}"
            }
            (jsonPath + suffix).removePrefix(".")
        }
        return Violation(name, "must not be null")
    }

这样,您将获得具有适当约束错误的良好输出。

您可以尝试直接为@ExceptionHandler声明MissingKotlinParameterException(尽管我已经尝试过了,但这不是出于某种原因),但是我不能保证它会起作用。

用于路径解析的代码示例摘自here