当前位置: 首页 > 知识库问答 >
问题:

bean验证不使用kotlin(JSR 380)

白修谨
2023-03-14
@Controller
@RequestMapping("/users")
class UserController {
    @PostMapping
    fun createUser(@Valid user: User, bindingResult: BindingResult): ModelAndView {
        return ModelAndView("someview", "user", user)
    }
}

这是用Kotlin编写的User类:

data class User(
    @field:NotEmpty
    var roles: MutableSet<@NotNull Role> = HashSet()
)

这就是测试:

@Test
internal fun shouldNotCreateNewTestWithInvalidParams() {
    mockMvc.perform(post("/users")
        .param("roles", "invalid role"))
        .andExpect(model().attributeHasFieldErrors("user",  "roles[]"))
}

无效的角色映射为NULL。

@Data // just lombok...
public class User {
    @NotEmpty
    private Set<@NotNull Role> roles = new HashSet<>();
}
private Ljava/util/Set; roles
@Ljavax/validation/constraints/NotEmpty;()
@Ljavax/validation/constraints/NotNull;() : FIELD, 0;
@Ljavax/validation/constraints/NotEmpty;() : FIELD, null
private Ljava/util/Set; roles
@Ljavax/validation/constraints/NotEmpty;()
@Lorg/jetbrains/annotations/NotNull;() // added because roles is not nullable in kotlin. this does not affect validation

这里有一个示例项目,以防您想尝试一些东西。

共有1个答案

艾自强
2023-03-14

确保使用jvm Target1.8或更高版本编译kotlin代码,并通过在编译时提供-xemit-jvm-type-annotations来启用此特性。

对于Spring Boot项目,您只需进行以下更改(使用Spring Boot 2.3.3和Kotlin 1.4.0测试):

  1. In your pom set the following property:
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.4.0</kotlin.version>
    </properties>
    
    <build>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <configuration>
                <args>
                    <arg>-Xjsr305=strict</arg>
                    <arg>-Xemit-jvm-type-annotations</arg>
                </args>
                <compilerPlugins>
                    <plugin>spring</plugin>
                </compilerPlugins>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-allopen</artifactId>
                    <version>${kotlin.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </build>
    

    项目示例

    import javax.validation.Constraint
    import javax.validation.Payload
    import kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS
    import kotlin.annotation.AnnotationTarget.CONSTRUCTOR
    import kotlin.annotation.AnnotationTarget.FIELD
    import kotlin.annotation.AnnotationTarget.FUNCTION
    import kotlin.annotation.AnnotationTarget.TYPE_PARAMETER
    import kotlin.annotation.AnnotationTarget.VALUE_PARAMETER
    import kotlin.reflect.KClass
    
    @MustBeDocumented
    @Constraint(validatedBy = [NoNullElementsValidator::class])
    @Target(allowedTargets = [FUNCTION, FIELD, ANNOTATION_CLASS, CONSTRUCTOR, VALUE_PARAMETER, TYPE_PARAMETER])
    @Retention(AnnotationRetention.RUNTIME)
    annotation class NoNullElements(
        val message: String = "must not contain null elements",
        val groups: Array<KClass<out Any>> = [],
        val payload: Array<KClass<out Payload>> = []
    )
    
    import javax.validation.ConstraintValidator
    import javax.validation.ConstraintValidatorContext
    
    class NoNullElementsValidator : ConstraintValidator<NoNullElements, Collection<Any>> {
        override fun isValid(value: Collection<Any>?, context: ConstraintValidatorContext): Boolean {
            // null values are valid
            if (value == null) {
                return true
            }
            return value.stream().noneMatch { it == null }
        }
    }
    
    data class User(
        @field:NotEmpty
        @field:NoNullElements
        var roles: MutableSet<Role> = HashSet()
    )
    

    现在所有艰难的验证都起作用了,结果的ConstrainViolution略有不同。例如,ElementTypePropertyPath是不同的,如下所示。

    Java:

    科特林:

 类似资料:
  • 我正在尝试使用自定义Bean验证来验证应该大于零的数值,但问题是使用如下单个自定义验证器来验证任何数值:整数、浮点数、双......: 整数int; @PositiveNumber双倍双; 这可能吗?

  • 我试图让Kotlin在spring-data-rest项目上使用JSR303验证。 给定以下数据类声明: 提前感谢您的帮助!

  • 首先,我是Vaadin7的新手。当我发现BeanFieldGroup.class时,我正在尝试一些vaadin演示。正如我所看到的,这个类将一个字段绑定到一个bean属性。在bean中,使用验证约束注释对属性进行注释(JSR303)。在本例中,我的pom.xml包含hibernate验证器依赖项: 我创建了validationmessage.properties文件,并在其中放了一些消息(带有匈牙

  • 但是,当我执行以下测试时,不会引发验证异常: 当保存一个已经持久化的对象时,我如何使验证器触发器?最好是通过Java配置。 我的验证依赖项:

  • 当我使用null email向/注册用户发送一个POST请求时,我希望它会说“Hey,you have null in email field”,但由于语句,它会在保存步骤中抛出NPE。当我用错误的电子邮件发送json时,如下所示: 它完美地通过了这个约束注释: 我试过的。我尝试在@validemail、@get:validemail、@field:validemail(kotlin data c

  • 问题内容: 我正在尝试使用此处指定的Java EE 6验证 http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html 我注释了一个简单的字段 文档说:“对于内置约束,可以使用默认实现”,但是我如何指定这一点。我的约束检查尚未启动。我希望它能在调用该字段的setter方法时起作用。我班上唯一的进口是 我如何/在哪里指定实现?我将约束放在简单POJ