Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make Spring show different validation bundle-based messages for the same validator on a class?

First, let me explain that I'm using Spring MVC 3.1.1, and Hibernate validation 4.2.0. I'm using validation annotations for various forms in my Spring application. Since my application needs to be localized, I've been using a resource bundle for my validation messages that looks somewhat like this:

# ValidationMessages.bundle
FieldMatch=Password and confirmation must match.

The corresponding class definition for this message looks like this:

@FieldMatch.List({
    @FieldMatch(first = "password", second = "passwordConfirmation")
})
public class RegistrationForm {
    // ...
}

I have this custom resource bundle set up in my appContext.xml, and my messages are being shown on the form without any issue.

Here's my dilemma, however. There is a new requirement that I must confirm more fields match. Right now I'm just confirming that two password fields match. Now my requirement is that I have to confirm email address too. I know this is a silly requirement, but I can't change it. So now the class definition will look like this:

@FieldMatch.List({
    @FieldMatch(first = "password", second = "passwordConfirmation")
    @FieldMatch(first = "email", second = "emailConfirmation")
})
public class RegistrationForm {
    // ...
}

Clearly, my current resource bundle will not work because I need two separate messages (one for each match). I've tried using message="{emails.must.match}" and then defining that message in the resource bundle, but it never actually shows the message, it just shows the actual text {email.must.match}.

So after all that explaining, my question is simple: How can I make each one of those FieldMatch validators at the class level have a different message that is defined in a resource bundle so it can be localized?

Thanks in advance for any help!

[EDIT] For those curious, this is the FieldMatch validator that I'm using.

UPDATE 5/23/2012 Here's the bean definition others have asked for:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>ErrorBundle</value>
            <value>ForgotPasswordBundle</value>
            <!-- etc etc -->
        </list>
    </property>
</bean>

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource"/>
</bean>
like image 503
Scott Anderson Avatar asked Apr 30 '12 18:04

Scott Anderson


People also ask

Where do I put ValidationMessages properties?

By default, ValidationMessages. properties can be located in root of my classpath.

What is @validated in spring?

@Validated annotation is a class-level annotation that we can use to tell Spring to validate parameters that are passed into a method of the annotated class. and. @Valid annotation on method parameters and fields to tell Spring that we want a method parameter or field to be validated.


2 Answers

Cases like this usually turn on something the OP did not include in the question. I guess this is because if the solution were simple or caused by something the OP thought it was caused by, they wouldn't have a problem. No judgment; I've done it.

So I present troubleshooting steps instead of a complete solution, because based on what you've said, it should work.

First, let's double check that it's not a weird interpolation problem and try message="{emails-must-match}".

If that doesn't work, well, it appears you used to have ValidationMessages.properties working. I'd go back to that (removing <property name="validationMessageSource" ref="messageSource"/> from the validator config) and see if you can get message="{emails.must.match}" to work with emails.must.match defined in ValidationMessages.properties. If that still doesn't work, go back to the default message you had using the key FieldMatch and see if you get that message for both error conditions.

That will help localize the problem.

like image 113
Old Pro Avatar answered Sep 26 '22 13:09

Old Pro


FieldMatch is using a JSR-303 validator (javax.validation.Validator), not a Spring validator (org.springframework.validation.Validator). Did you config the message source like:

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

and of course the corresponding messageSource?

like image 41
ChrLipp Avatar answered Sep 26 '22 13:09

ChrLipp