【问题标题】:Hibernate Validator method or constructor validationHibernate Validator 方法或构造函数验证
【发布时间】:2017-05-09 02:05:49
【问题描述】:

如何使用 Hibernate 验证器来验证构造函数或方法中的参数?我希望在创建 ValueObject 之前进行验证,因此我可以抛出异常而不创建对象,除非所有参数都有效。

如果可能的话,基本上我会尝试使用注释而不是这样做:

public class ConditionalPerson {
    private String name;
    private String surname;
    private int age;

    public ConditionalPerson(String name, String surname, int age){
        if (name == null || surname == null || age < 1) {
            throw new IllegalArgumentException();
        }
        this.name = name;
        this.surname = surname;
        this.age = age;
    }
}

我尝试过像这样关注docs,这似乎可行,但仍会导致对象被创建。

public class Person {
    @NotNull(message = "Name can't be null")
    @NotEmpty(message = "Name can't be empty")
    @Length(min=1)
    private String name;

    @NotNull(message = "Surname can't be null")
    @NotEmpty(message = "Surname can't be empty")
    @Length(min=1)
    private String surname;

    @Range(min=100, max=200)
    private int age;

    public Person(String name, String surname, int age){
        this.name = name;
        this.surname = surname;
        this.age = age;
    }
}

给构造函数参数加注解好像没有效果

public Person(@NotNull String name, 
              @NotNull String surname, 
              @Range(min=100, max=200) int age) { 
    ...
}

我是如何创建对象的:

public class Example {
    Person person;
    ConditionalPerson person2;

    public static void main(String[] args) {
        Example example = new Example();
        example.makePerson();
        example.makeConditionalPerson();
    }

    public void makePerson() {
        person = new Person(null, "", 12);
        Validator validator = ValidatorSingleton.getValidator();

        Set<ConstraintViolation<Person>> violations = validator.validate(person);

        if (violations.size() > 0) {
            throw new IllegalArgumentException();
        }
    }

    public void makeConditionalPerson() {
        person2 = new ConditionalPerson(null, "", 123);
    }
}

验证器:

public class ValidatorSingleton {
    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private static final javax.validation.Validator validator = factory.getValidator();

    private ValidatorSingleton(){}

    public static Validator getValidator() {
        return validator;
    }
}

【问题讨论】:

    标签: java aspectj bean-validation hibernate-validator oval


    【解决方案1】:

    对于发现此帖子的其他任何人。 我稍微改变了我的方法,并使用OVal Validation & AspectJ 而不是 Hibernate 来实现这一点。

    除了我需要在类上方添加@Guarded之外,基本上与上面的示例相同:

    @Guarded
    public class Person {
        private String name;
        private String surname;
        private int age;
    
        public Person(@NotNull String name, @NotNull String surname, @Range(min=100, max=200) int age){
            this.name = name;
            this.surname = surname;
            this.age = age;
        }
    }
    

    然后在你的 build.gradle 添加:

    buildscript {
        repositories {
            jcenter()
            mavenCentral()
        }
        dependencies {
            classpath 'org.aspectj:aspectjtools:1.8.10'
        }
    }
    dependencies {
        compile 'org.aspectj:aspectjrt:1.8.1'
        compile 'net.sf.oval:oval:1.86'
    }
    
    tasks.withType(JavaCompile) {
        doLast {
            String[] args = ["-showWeaveInfo",
                             "-1.8",
                             "-inpath", destinationDir.toString(),
                             "-aspectpath", classpath.asPath,
                             "-d", destinationDir.toString(),
                             "-classpath", classpath.asPath]
    
            MessageHandler handler = new MessageHandler(true);
            new Main().run(args, handler)
        }
    

    【讨论】:

      【解决方案2】:

      您可以使用休眠验证器执行此操作,使用反射来验证参数:

      public class PersonTest {
      
      private static ExecutableValidator executableValidator;
      
      @BeforeClass
      public static void setUp() {
          ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
          executableValidator = factory.getValidator().forExecutables();
      }
      @Test
      public void test() throws NoSuchMethodException {
          Constructor<Person> constructor = 
                 Person.class.getConstructor(String.class, String.class, int.class);
      
          Set<ConstraintViolation<Person>> violations = 
               executableValidator.validateConstructorParameters(constructor, new Object[]{null, "", 12});
               assertEquals(2, violations.size());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        • 2017-04-23
        • 1970-01-01
        相关资源
        最近更新 更多