Я знаю, что об этом спрашивали тысячи раз, но это действительно кошмар. В течение нескольких дней я пытался выяснить, как настроить 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