【问题标题】:Spring not null validation throwing HttpMessageNotReadableException instead of MethodArgumentNotValidException in kotlinSpring not null 验证在 kotlin 中抛出 HttpMessageNotReadableException 而不是 MethodArgumentNotValidException
【发布时间】:2019-02-21 00:07:41
【问题描述】:

我正在使用 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 异常,但如果我向name 字段发送空值,则会引发HttpMessageNotReadableException 异常。有谁知道是否可以将 null 传递给标有 @NotNull 的字段以在 Kotlin 中也抛出 MethodArgumentNotValidException

【问题讨论】:

    标签: spring rest validation kotlin


    【解决方案1】:

    所以您的问题是您将名称字段指定为不可为空,默认情况下,kotlin 的杰克逊模块将检查它并在 json 映射过程中抛出MissingKotlinParameterException 导致的HttpMessageNotReadableException。如果您将name 标记为可空json 映射将通过并使用@Valid 进入春季验证阶段,那么我们将获得MethodArgumentNotValidException

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

    【讨论】:

      【解决方案2】:

      您可以通过提供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")
          }
      

      通过这种方式,您可以获得带有适当约束错误的良好输出。

      你可以尝试直接为MissingKotlinParameterException声明@ExceptionHandler(虽然我试过了,但不是什么原因),但我不能保证它会起作用。

      路径解析的代码示例取自here

      【讨论】:

        猜你喜欢
        • 2014-06-06
        • 2014-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-20
        相关资源
        最近更新 更多