JSON中Int字段的Kotlin + Spring Boot默认值

时间:2018-06-26 14:15:45

标签: spring kotlin

我正在用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

如何使此字段为必填字段?

3 个答案:

答案 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注释也不支持基元或数字变量。它只是验证StringArrayMapList的长度...因此,只需用@Min@Max对其进行注释。因此,默认值0将不再有效。

也可以使用Integer代替Int来使可为空的对象验证,以便仅检查@NotNull是否想要负数或0有效,而无需获取默认值0