Проверка правильности метода или конструктора Hibernate Validator
Как я могу использовать валидатор 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;
}
}
Я пытался следовать этим документам, которые, кажется, работают, но все же приводят к созданию объекта.
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 ответа
Для всех, кто найдет этот пост. Я немного изменил свой подход и получил это, используя 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)
}
Вы можете сделать это с помощью hibernate validator, используя refection для проверки аргументов:
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());
}
}