我正在用Kotlin + Spring Boot + Hibernate编写简单的CRUD,并想到了这个问题:
我在User
类中有一个名为age
的字段,然后键入Int
import javax.persistence.*
import javax.validation.constraints.NotBlank
import javax.validation.constraints.Size
@Entity
@Table(name = "users")
data class User(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long,
@NotBlank
@Column(unique = true)
@Size(min = 1, max = 100)
val username: String,
@NotBlank
@Size(max = 50)
val firstName: String,
@Size(max = 50)
val lastName: String?,
@Size(min = 1, max = 100)
val age: Int
)
然后我有一个创建用户的帖子请求
@PostMapping
fun post(@RequestBody user: User): User {
log.debug("POST: {}", user)
return userRepository.save(user)
}
问题是,当我错过JSON中的age
字段时,它不会响应400错误,而是默认为0
。
如何使此字段为必填字段?
答案 0 :(得分:2)
我认为,更大的问题是您将同一类(您的实体)用于多种用途。这使此类非常不灵活,因为您无法使其适应REST端点的需求以及Hibernate的需求。
我要做的是在两者之间有一个界限(建议像Clean Architecture那样做):
data class UserDTO(val id: Long?,
var username: String?,
var firstName: String?,
var lastName: String?,
var age: Int?) {
fun toUser() = User(
id = id ?: signalError(),
username = username ?: signalError(),
firstName = firstName ?: signalError(),
lastName = lastName ?: signalError(),
age = age ?: signalError())
private fun signalError() : Nothing = throw IllegalArgumentException(
"Missing parameter in UserDTO.")
}
答案 1 :(得分:1)
借助此post,我解决了该问题, 也感谢@Adam Arold展示了最佳做法。
我创建了一个新的UserDTO
类:
import ai.leavingstone.flywayspringdemo.domain.User
import javax.validation.constraints.*
data class UserDTO(
private val id: Long = -1,
@field:NotBlank
@field:Size(min = 1, max = 100)
private val username: String,
@field:NotBlank
@field:Size(max = 50)
private val firstName: String,
@field:Size(max = 50)
private val lastName: String?,
@field:NotNull
private val age: Int?
) {
fun toUser(): User = User(
id,
username,
firstName,
lastName,
age!!
)
}
在没有数据验证批注起作用之前,在添加@field
前缀之后它可以正常工作。 @NotNull
上的Int
也可以使用,并且id
字段的默认值也是如此。
答案 2 :(得分:0)
您应该使用@Valid @RequestBody user: User
作为方法参数,以便spring验证给定的主体。默认情况下应该这样做,但以防万一记下来,这样对新员工等更好。
@@ Size
注释也不支持基元或数字变量。它只是验证String
,Array
,Map
,List
的长度...因此,只需用@Min
和@Max
对其进行注释。因此,默认值0将不再有效。
也可以使用Integer
代替Int
来使可为空的对象验证,以便仅检查@NotNull
是否想要负数或0有效,而无需获取默认值0