验证失败时不会抛出 MethodArgumentNotValidException
MethodArgumentNotValidException not thrown in case of validation fail
我正尝试按照 this 教程在 Spring REST 中实施验证。不过,与教程不同,我的代码在 Koltin 中。
我的代码如下-
实体class
@Entity
class PodcastEntity(@Id @GeneratedValue(strategy = GenerationType.AUTO) @NotNull
var id: Long = 0,
@field:NotEmpty(message = "Please provide an author")
var author: String,
@field:NotEmpty(message = "Please provide a title")
var title: String,
@field:NotEmpty(message = "Please provide a description")
var description: String,
@field:NotEmpty(message = "Please provide category one")
var categoryOne: String,
@field:NotEmpty(message = "Please provide category two")
var categoryTwo: String,
var filePath: String = "")
我的post方法在controller
-
中是这样的
@PostMapping("details")
fun addPodcast(@Valid @RequestBody podcastEntity: PodcastEntity) {
podcastService.addPodcast(podcastEntity)
}
我在postman中的POST请求是这样的-
{
"author" : "me 3",
"title" : "File three",
"description" : "this is a test desc"
}
由于缺少categoryOne
和categoryTwo
并且我没有自己处理异常,根据教程我的控制台应该显示MethodArgumentNotValidException
。但是,我没有得到这样的例外。我得到的是 HttpMessageNotReadableException
异常 -
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Instantiation of [simple type, class com.krtkush.test.entities.PodcastEntity] value failed for JSON property categoryOne due to missing (therefore NULL) value for creator parameter categoryOne which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class com.krtkush.test.entities.PodcastEntity] value failed for JSON property categoryOne due to missing (therefore NULL) value for creator parameter categoryOne which is a non-nullable type at [Source: (PushbackInputStream); line: 5, column: 1] (through reference chain: com.krtkush.test.entities.PodcastEntity["categoryOne"])]
我不明白我哪里出错了。请帮忙?
您可以通过提供 HttpMessageNotReadableException
处理程序来处理这个问题
然后检查主要原因是否是 MissingKotlinParameterException
.
之后,您可以提供自定义验证错误。
@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
。
根据问题回答
根据 Damian 的 SO link 在他的回答中,我发现第一个答案确实很有帮助而且更合适。我修改了@Entitiy class,使所需的字段可以为空(?
),就像这样-
@Entity
class PodcastEntity(@Id @GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0,
@field:NotEmpty(message = "Please provide an author")
var author: String?,
@field:NotEmpty(message = "Please provide a title")
var title: String?,
@field:NotEmpty(message = "Please provide a description")
var description: String?,
@field:NotEmpty(message = "Please provide category one")
var categoryOne: String?,
@field:NotEmpty(message = "Please provide category two")
var categoryTwo: String?,
var filePath: String = "")
这确保代码在所有三种情况下都抛出 MethodArgumentNotValidException
- 1. 空参数 2. null
参数 3. 缺少参数
我正尝试按照 this 教程在 Spring REST 中实施验证。不过,与教程不同,我的代码在 Koltin 中。
我的代码如下-
实体class
@Entity
class PodcastEntity(@Id @GeneratedValue(strategy = GenerationType.AUTO) @NotNull
var id: Long = 0,
@field:NotEmpty(message = "Please provide an author")
var author: String,
@field:NotEmpty(message = "Please provide a title")
var title: String,
@field:NotEmpty(message = "Please provide a description")
var description: String,
@field:NotEmpty(message = "Please provide category one")
var categoryOne: String,
@field:NotEmpty(message = "Please provide category two")
var categoryTwo: String,
var filePath: String = "")
我的post方法在controller
-
@PostMapping("details")
fun addPodcast(@Valid @RequestBody podcastEntity: PodcastEntity) {
podcastService.addPodcast(podcastEntity)
}
我在postman中的POST请求是这样的-
{
"author" : "me 3",
"title" : "File three",
"description" : "this is a test desc"
}
由于缺少categoryOne
和categoryTwo
并且我没有自己处理异常,根据教程我的控制台应该显示MethodArgumentNotValidException
。但是,我没有得到这样的例外。我得到的是 HttpMessageNotReadableException
异常 -
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Instantiation of [simple type, class com.krtkush.test.entities.PodcastEntity] value failed for JSON property categoryOne due to missing (therefore NULL) value for creator parameter categoryOne which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class com.krtkush.test.entities.PodcastEntity] value failed for JSON property categoryOne due to missing (therefore NULL) value for creator parameter categoryOne which is a non-nullable type at [Source: (PushbackInputStream); line: 5, column: 1] (through reference chain: com.krtkush.test.entities.PodcastEntity["categoryOne"])]
我不明白我哪里出错了。请帮忙?
您可以通过提供 HttpMessageNotReadableException
处理程序来处理这个问题
然后检查主要原因是否是 MissingKotlinParameterException
.
之后,您可以提供自定义验证错误。
@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
。
根据问题回答
根据 Damian 的 SO link 在他的回答中,我发现第一个答案确实很有帮助而且更合适。我修改了@Entitiy class,使所需的字段可以为空(?
),就像这样-
@Entity
class PodcastEntity(@Id @GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0,
@field:NotEmpty(message = "Please provide an author")
var author: String?,
@field:NotEmpty(message = "Please provide a title")
var title: String?,
@field:NotEmpty(message = "Please provide a description")
var description: String?,
@field:NotEmpty(message = "Please provide category one")
var categoryOne: String?,
@field:NotEmpty(message = "Please provide category two")
var categoryTwo: String?,
var filePath: String = "")
这确保代码在所有三种情况下都抛出 MethodArgumentNotValidException
- 1. 空参数 2. null
参数 3. 缺少参数