Как запустить валидацию Javax вручную с помощью отражения или любым другим способом? - PullRequest
0 голосов
/ 23 октября 2018

Я использую validation-api-2.0.1.Final и hibernate-validator-6.0.13.Final.Я хотел бы выполнить проверку для приведенного ниже случая:

Я создал пользовательскую проверку для проверки List<Map<String,Object>>

BookInfo.java

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {BookInfoValidator.class}
)
public @interface BookInfo {
    String message() default "Should not be empty";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

BookInfoValidator.java

public class BookInfoValidator implements ConstraintValidator<ValidateUserInfo, List<Map<String, Object>>> {

    private final ContentRepositoryClient contentRepository;

    public ValidateUserInfoValidator(ContentRepositoryClient contentRepository) {
        this.contentRepository = contentRepository;
    }

    @Override
    public void initialize(ValidateUserInfo constraintAnnotation) {

    }

    @Override
    public boolean isValid(List<Map<String,Object>> map, ConstraintValidatorContext constraintValidatorContext) {
        //In the list of Map the key will be "text,email,date etc etc" based on the key i would like to
        //validate with the proper validation constraints
        //ex) for Email invoke javax.validation.constraints.Email.class from validation-api
        //I am not sure how to manually invoke the validation annotations.
        return false;
    }
}

BookInfoView.java

class BookInfoView {
        @BookInfo
        private List<Map<String, Object>> bookInfos;
    }

В списке карт ключом будет «текст,электронная почта, дата и т. д.Основываясь на ключе, который я хотел бы проверить с правильным исключением ограничений проверки для Email, вызовите javax.validation.constraints.Email.class из validation-api.Я не уверен, как вручную вызывать аннотации проверки.

Любая подсказка или помощь будут высоко оценены.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Нет «приятного» способа доступа к реализациям валидатора для ограничений (электронная почта, не ноль и т. Д.).Хотя вы можете создавать экземпляры этих валидаторов и сохранять их в своем BookInfoValidator, вам потребуется проделать большую дополнительную работу.Что касается каждого валидатора, его метод ConstraintValidator#initialize().Хотя в случае простых ограничений, таких как @NotNull, на самом деле нет необходимости инициализировать, такую ​​же проверку можно легко выполнить без этого валидатора.А в случае более сложных, таких как @Email, вам потребуется создать собственный прокси-класс для аннотации, чтобы можно было правильно инициализировать валидатор ограничения.

С учетом сказанного я бы предложил написать класс обертки для вашего Map, что-то вроде:

public class BookInfoWrapper {
    private final Map<String, Object> data;

    public BookInfoWrapper(Map<String, Object> data) {
        this.data = data;
    }

    @NotNull
    public Map<String, Object> getUser(){
        return (Map<String, Object>) data.get( "user" );
    }

    @Email
    public String getEmail(){
        return Objects.toString(( getUser() ).get( "email" ));
    }

    // and any other constraints you need
}

, а затем преобразовать список карт в эти обертки перед проверкой.

Я также вижу, что у вас есть хранилище в вашем валидаторе, поэтому я думаю, что вы, возможно, захотите вывести правила «динамически».В таком случае вы можете попробовать программный API , предоставляемый Hibernate Validator.Используя его, вы сможете создавать необходимые правила на основе данных, извлеченных из базы данных.Но все же сначала вам нужно будет обернуть карты.

Подводя итог, к сожалению, пока нет хорошего и простого решения для вашего конкретного случая.Мы работаем над проверкой объектов свободной формы, но нам потребуется некоторое время, чтобы ее можно было опубликовать.Поэтому я бы посоветовал вам либо

  • написать проверочные проверки самостоятельно в своем BookInfoValidator без использования встроенных ограничений.
  • используйте подход обертки, описанный выше.
0 голосов
/ 23 октября 2018

Я не уверен, как вручную вызывать аннотации проверки.

Я отвечаю на приведенные выше строки. Да , можно вызвать валидацию программно, и в случае неудачи валидации вы получите все сообщения о сбоях в наборе.Ниже приведены шаги, чтобы сделать то же самое:

  1. Build ValidatorFactory
  2. Получить экземпляр Validator от ValidatorFactory
  3. Выполнить проверку, используяvalidate() method
  4. Обработка результата проверки constraintViolations.iterator().next().getMessage()

Показать некоторый код, ниже приведен фрагмент кода для всех четырех упомянутых выше шагов:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<BookInfoView>> constraintViolations = validator.validate(bookInfoViewObj);
assertEquals( "Should not be empty", constraintViolations.iterator().next().getMessage() );
* 1026Платформа Hibernate Validator предоставляет различные другие возможности для проверки одного или нескольких объектов и последующей обработки результата.Лучше взгляните на официальный документ .
...