使用Hibernate Validator验证没有JavaBean约定的POJO

时间:2016-12-12 14:34:53

标签: java javabeans bean-validation hibernate-validator

有一个代码库广泛使用Google AutoValue来创建不符合JavaBean约定的值类,即。即而不是getFoo(),相应的方法将简单地命名为foo()。不幸的是,Hibernate Validator只能验证开箱即用的JavaBean getter或类属性,因此AutoValue类的验证会无声地失败。

如何自定义Hibernate Validator以验证不符合JavaBean约定的POJO(即使用getsetis / has前缀)?

实施例

HibernateValidatorAutoValueTest.java

import com.google.auto.value.AutoValue;
import org.hibernate.validator.constraints.NotBlank;
import org.junit.Test;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class HibernateValidatorAutoValueTest {
    @Test
    public void test() {
        final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        final Validator validator = factory.getValidator();

        final Bean validBean = Bean.create("Valid", 100);
        assertTrue("Valid bean should not have constraint violations", validator.validate(validBean).isEmpty());

        final Bean invalidBean = Bean.create("", -1);
        assertFalse("Invalid bean should have constraint violations", validator.validate(invalidBean).isEmpty());
    }

    @AutoValue
    public static abstract class Bean {
        @NotBlank
        public abstract String text();

        @NotNull
        @Min(42L)
        public abstract Integer number();

        public static Bean create(String text, Integer number) {
            return new AutoValue_HibernateValidatorAutoValueTest_Bean(text, number);
        }
    }
}

的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <prerequisites>
        <maven>3.0.1</maven>
    </prerequisites>

    <groupId>org.example</groupId>
    <artifactId>hibernate-validator-auto-value</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.3.4.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.el</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.auto.value</groupId>
            <artifactId>auto-value</artifactId>
            <version>1.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

1 个答案:

答案 0 :(得分:2)

现在不可能,Bean Validation确实以JavaBeans为中心。如果您愿意,请在我们的Preserve Options中提出问题,以便我们可以在参考实现中进行探索,但这需要进行一些更改。

目前可能的一种解决方法可能是使用XML或HV编程API进行约束声明,以将约束应用于生成的这些类型的实现的字段。这意味着对getter访问进行字段访问,当然,它并不像将约束直接置于自动值类型的getter定义那样简洁。