我正在使用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中。
答案 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