I'm trying to set up a custom message source for Hibernate Validator 4.1 through Spring 3.0. I've set up the necessary configuration:
<!-- JSR-303 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
The translations are served from my message source, but it seems that the replacement tokens in the messages themselves are looked up in the message source, i.e. for a:
my.message=the property {prop} is invalid
there are calls to look up 'prop' in the messageSource. Going into ResourceBundleMessageInterpolator.interpolateMessage
I note that the javadoc states:
Runs the message interpolation according to algorithm specified in JSR 303.
Note: Look-ups in user bundles is recursive whereas look-ups in default bundle are not!
This looks to me like the recursion will always take place for a user-specified bundle, so in effect I can not translate standard messages like the one for Size.
How can I plug-in my own message source and be able to have parameters be replaced in the message?
Hibernate Validator's ResourceBundleMessageInterpolator create two instances of ResourceBundleLocator (i.e. PlatformResourceBundleLocator) one for UserDefined validation messages - userResourceBundleLocator and the other for JSR-303 Standard validation messages - defaultResourceBundleLocator.
Any text that appears within two curly braces e.g.
{someText}
in the message is treated as replacementToken. ResourceBundleMessageInterpolator tries to find the matching value which can replace the replacementToken in ResourceBundleLocators.So, if you put a Standard JSR-303 message in custom ResourceBundle say,
validation_erros.properties
, it will be replaced by your custom message. See in this EXAMPLE Standard NotNull validation message 'may not be null' has been replaced by custom 'MyNotNullMessage' message.After going through both ResourceBundleLocators, ResourceBundleMessageInterpolator finds for more replaceTokens in the resolvedMessage (resolved by both bundles). These replacementToken are nothing but the names of Annotation's attributes, if such replaceTokens are found in the resolvedMessage, they are replaced by the values of matching Annotation attributes.
ResourceBundleMessageInterpolator.java [Line 168, 4.1.0.Final]
Providing an example to replace {prop} with custom value, I hope it will help you....
MyNotNull.java
MyNotNullValidator.java
User.java
validation_errors.properties
Test
Output