2017-05-09 60 views
1

如何使用Hibernate驗證器驗證構造函數或方法內的參數?我希望在創建ValueObject之前進行驗證,這樣我可以引發異常並且不會創建對象,除非所有參數都有效。Hibernate Validator方法或構造函數驗證

基本上我試圖使用,而不是如果可能的話做這樣的註解:

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; 
    } 
} 

回答

2

對於任何人來說e找到這篇文章。 我稍微改變了我的方法,並使用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) 
    } 
0

你可以這樣做與Hibernate驗證使用反射來驗證參數:

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()); 
    } 
}