Пользовательская проверка Spring MVC и JSR 303 с пользовательским пакетом ресурсов - PullRequest
4 голосов
/ 31 марта 2012

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

Вот часть моего веб-контекста:

    <!-- i18n handling -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="i18n.eSporx" />
    </bean>

Вот часть контекста моего приложения:

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
            <property name="validationMessageSource" ref="messageSource"/>
    </bean>

И, наконец, мое (кросс-поле на уровне класса) пользовательское ограничение и его валидатор:

@Documented
@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = CrossDateConstraintsValidator.class)
public @interface CrossDateConstraints {

    String message() default "crossdate.validation.error";

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

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

    String startDateFieldName() default "startDate";

    String endDateFieldName() default "endDate";
}


@Component
@Scope(SCOPE_PROTOTYPE)
public class CrossDateConstraintsValidator implements ConstraintValidator<CrossDateConstraints, Object> {

    private String startDateField;
    private String endDateField;
    private String message;

    @Override
    public void initialize(final CrossDateConstraints constraintAnnotation) {
        startDateField = constraintAnnotation.startDateFieldName();
        endDateField = constraintAnnotation.endDateFieldName();
        message = constraintAnnotation.message();
    }

    @Override
    public boolean isValid(final Object annotatedClassInstance, final ConstraintValidatorContext context) {
        boolean isValid = false;
        try {
            Date startDate = getDateFieldValue(annotatedClassInstance, startDateField);
            Date endDate = getDateFieldValue(annotatedClassInstance, endDateField);
            isValid = endDate.after(startDate);

            if (!isValid) {
                forceErrorsOnBothFields(context);
            }

            return isValid;
        }
        catch (Exception e) {
            return isValid;
        }
    }

    private void forceErrorsOnBothFields(final ConstraintValidatorContext context) {
        context.buildConstraintViolationWithTemplate(message).addNode(startDateField).addConstraintViolation();
        context.buildConstraintViolationWithTemplate(message).addNode(endDateField).addConstraintViolation();
    }

    private Date getDateFieldValue(final Object annotatedClassInstance, final String fieldName) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        Method dateGetter = new PropertyDescriptor(fieldName, annotatedClassInstance.getClass()).getReadMethod();
        Date date = (Date) dateGetter.invoke(annotatedClassInstance);
        return date;
    }
}

Пакет ресурсов расположен в src/main/resources/i18n/eSporx.properties (с его вариантами локали). Такие вещи как <spring:message code="my.key" /> в моих JSP работают нормально. Однако всякий раз, когда возникает ошибка CrossDateConstraints, все, что я могу прочитать, это «crossdate.validation.error», даже если ключ хранится в файле свойств!

Если у вас есть идея, пожалуйста, скажите мне :) Это так расстраивает.

Rolf

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Чтобы включить интерполяцию сообщения, вы должны заключить его в фигурные скобки, например:

String message() default "{crossdate.validation.error}";

См. Также 2.2.4.Интерполяция сообщений глава в руководстве по Hibernate Validator.

1 голос
/ 31 марта 2012

Старые версии hibernate-validator не позволяют переопределить пакет ресурсов по умолчанию.Убедитесь, что вы используете последнюю версию, такую ​​как 4.2.0.Final.

То есть, даже если вы уже используете последнюю версию, эта версия может быть переопределена той, которая встроена в ваш сервер приложений.Например, Glassfish 3.0 встраивает версию hibernate-validator, которая не поддерживает переопределение пакета ресурсов.

...