在用Kotlin构建的Spring应用程序中,我想对看起来像这样的数据类使用bean验证。
data class CustomerDto(
@field: NotBlank
val firstName: String,
@field: NotBlank
val lastName: String)
在向客户端点发送带有空名字的帖子时,我希望获得约束验证,但是由于字段不允许空值,所以我没有得到验证,而是得到了以下错误。
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Instantiation of [simple type, class pkg.CustomerDto] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class pkg.CustomerDto] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type\n at [Source: (PushbackInputStream); line: 19, column: 1] (through reference chain: pkg.CustomerDto[\"firstName\"])",
"path": "/shop/5/customer"
是否还有其他选项可以将dto字段标记为非可选,并且仍然会违反约束?当我将它们标记为可选时,我必须使用!!将它们映射到我的实体时在代码中不可为空的字段上输入
。谢谢。
答案 0 :(得分:1)
I believe you are going at it the wrong way.
Kotlin's null safety operators exact purpose is to enforce you to explicitly express nullability behavior in your code in order to drastically minimize NPE, or at least make sure you knowingly caused them yourself :). In your (or any MVC like access pattern) case, you are faced with the following scenario
Though it makes sense in terms of logical flow, it's actually a violation that may result in an NPE, because nothing in the model/contract guarantees these fields won't be null
Still, In java, you'd have just made that final assumption using a getter(you'd have been using a getter anyway, it's java, right?).
Well - it's no different in kotlin, if that's what you require:
data class CustomerDto(@field:NotNull
@JsonProperty("firstName") private val _firstName: String? = null,
@field:NotNull
@JsonProperty("lastName") private val _lastName: String? = null) {
val firstName get() = _firstName!!
val lastName get() = _lastName!!
}
(This examples assumes you are using jackson
for JSON de/serialization)
While still manually forcing non-nullability using the !!
operator (which is something you wanted to avoid), you are now abstracting that aspect from the rest of your codebase, getting that java-getter like behavior
答案 1 :(得分:0)
我认为一个更好的解决方案是在属性中使用Kotlin的默认值:
data class CustomerDto(
@field: NotBlank
val firstName: String="",
@field: NotBlank
val lastName: String="")
名字和姓氏属性将始终具有一个值(来自json或默认值=“”)。该解决方案并不完美,但可以按预期工作。