簡體   English   中英

Spring非空驗證在kotlin中拋出HttpMessageNotReadableException而不是MethodArgumentNotValidException

[英]Spring not null validation throwing HttpMessageNotReadableException instead of MethodArgumentNotValidException in 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的字段,以便在 Kotlin 中也拋出MethodArgumentNotValidException

所以你的問題是你將 name 字段指定為不可為空,默認情況下,kotlin 的 jackson 模塊會檢查它並拋出HttpMessageNotReadableException ,這是在 json 映射過程中由MissingKotlinParameterException引起的。 如果您將name標記為可空的 json 映射將通過並使用@Valid進入 spring 驗證階段, @Valid我們將得到MethodArgumentNotValidException

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

您可以通過提供HttpMessageNotReadableException處理程序然后檢查根本原因是否為MissingKotlinParameterException來處理此問題。

之后,您可以提供自定義驗證錯誤。 我正在使用zalando-problem ,所以語法與 vanilla spring 有點不同,但你明白了:

    @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 (雖然我已經嘗試過,但不是MissingKotlinParameterException某種原因),但我不能保證它會起作用。

路徑解析的代碼示例取自此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM