Пользовательская проверка bean-компонента не выполняет `@inject` CDI-бинов и не интерполирует сообщение?

Я использую GF4 с проверкой bean-компонентов. Я пытаюсь @Inject служебный компонент в своем пользовательском валидаторе, но получаю значение null.

 public class TestValidator implements ConstraintValidator<>{
   @Inject Service myService;
}

Разве это не должно работать с JEE7?

Кроме того, я пытаюсь найти встроенную динамическую интерполяцию сообщений (без написания собственного MessageInterpolator). Я видел несколько примеров, но они не очень ясны. Я ищу, чтобы передать динамические параметры из файла ConstraintValidator.isValid. Например:

Message_test={значение} недействительно

И каким-то образом сплести это так же, как вы можете статически интерполировать значения Annotation, например. size_msg={min}-{max} выходит за пределы допустимого диапазона.


person Ioannis Deligiannis    schedule 23.11.2013    source источник


Ответы (1)


Да, внедрение зависимостей в валидаторы должно быть возможным в Java EE 7/Bean Validation 1.1 в целом.

Как вы выполняете проверку и как вы получаете объект Validator? Обратите внимание, что DI работает по умолчанию только для валидаторов, управляемых контейнером, то есть тех, которые вы получаете через @Inject или поиск JNDI. Если вы самостоятельно загрузите валидатор с помощью BV bootstrap API, этот валидатор не будет поддерживать CDI.

Что касается интерполяции сообщений, вы можете обратиться к проверенному значению, используя ${validatedValue}. Если вы работаете с Hibernate Validator 5.1.0.Alpha1 или более поздней версии, у вас также есть возможность добавлять дополнительные объекты в контекст сообщения изнутри ConstraintValidator#isValid() следующим образом:

public boolean isValid(Date value, ConstraintValidatorContext context) {
    Date now = GregorianCalendar.getInstance().getTime();

    if ( value.before( now ) ) {
        HibernateConstraintValidatorContext hibernateContext =
                context.unwrap( HibernateConstraintValidatorContext.class );

        hibernateContext.disableDefaultConstraintViolation();
        hibernateContext.addExpressionVariable( "now", now )
                .buildConstraintViolationWithTemplate( "Must be after ${now}" )
                .addConstraintViolation();

        return false;
    }

    return true;
}
person Gunnar    schedule 25.11.2013
comment
Спасибо за Ваш ответ. Я использую @Named @ApplicationScoped для определения своих сервисов. Проверка запускается через JSF 2.2, поэтому я предполагаю, что она будет загружена через CDI. Внутри моего валидатора я использую @Inject для ссылки на свой сервисный компонент. Что касается спящего режима, я бы не хотел связывать свое приложение с какой-либо реализацией. - person Ioannis Deligiannis; 26.11.2013
comment
Мне удалось решить проблему. Если для бина JSF установлена ​​аннотация Validation, то служба внедряется правильно. Если для бина JPA установлена ​​аннотация проверки, то это не так. Я предполагаю, что это нормально, потому что службы определены как @Named/@ApplicationScoped, поэтому они недоступны в контексте спящего режима CDI. - person Ioannis Deligiannis; 30.11.2013