I wrote a custom Hibernate validation constraint for Money class:
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = MoneyLimitedValidator.class)
@Documented
public @interface MoneyLimited {
String message() default "{error.validation.money.limited}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
It works fine except error message. I see very strange behaviour: resource bundle found and message resolved by name, but it wrapped into special chars which usually appears if message can't be resolved by name:
??Incorrect sum value._en_EN??
Here Incorrect sum value.
is a correct message, which is accepted by name error.validation.money.limited
. Originaly my message looks so:
error.validation.money.limited = Incorrect sum value.
I tried to remove {} braces from message name into MoneyLimited#message()
, but nothing changes (even more strange).
I specified my validation message bundle as described in this answer:
<annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
So the question is: how to fix message?
I'm using Spring Framework 3.2.4.RELEASE and Hibernate Validator 4.3.1.Final.
I'm found the reason of double resolving. I didn't mentioned before, that I'm using Thymeleaf as template engine (which is using SpringEL). There are an useful snippet in example app, which I just copy-paste (shame on me) and forgot about:
<div class="errors" th:if="${#fields.hasErrors('*')}" th:fragment="validationErrorTpl">
<ul>
<li th:each="err : ${#fields.errors('*')}" th:text="#{${err}}">Input is incorrect</li>
</ul>
</div>
As you can see ${err}
variable enclosed in #{}
, which is actually resolving message from bundle. So with braces in validation constraint, message was resolved twice: on annotation level and in view template.