简体   繁体   中英

How to use annotation validation in Spring with error message gotten from properties file?

I'm a Spring newbie.

I set up validation in my domain class like this:

public class Worker {

    @NotNull(message="Name must be input")
    @Size(min=1,max=50, message="Name must not exceed 50 characters")
    private String name;
...

}

Here's the jsp file:

<form:input path="code" readonly="false" />
<font color="red"><form:errors path="code" />

And the controller code:

@RequestMapping(value="/test",method=RequestMethod.POST)
    public void form(@Valid Worker worker, BindingResult result) {

        if (result.hasErrors()) {
            return;
        }
...

It works, but how can I replace "Name must not exceed 50 characters" with some text (like worker.name.overflow) in my messageSource? May I need to add a messageResolver into BindingResult?

All the search result seems to say about writing a custom Validator class, but I want to use annotation for now. I'm pretty sure there's a way, because in this question someone has done that.

To tell hibernate validator to do a lookup on a code put the value of message in braces. eg, @NotNull(message="{worker.name.NotNull}" then put the translation in ValidationMessages.properties in the root of your classpath. (/WEB-INF/classes, resources folder in maven, etc.)

The validator implementation looks those up independently on its own, and they go on the BindingResult already translated as the default message. Happens outside of the Spring messagesource. You could in theory override LocalValidatorFactory bean to put the validator's message output onto the Errors object as the code and then leave the braces off in the annotation so that the Hibernate Validator passes it through. The source code that turns JSR-303 ConstraintViolations into spring Errors is simple enough to read and extend. It just puts the name of the annotation on as code, the annotation properties as args, and then the validator's translation as the default message.

Can see it here: https://src.springframework.org/svn/spring-framework/trunk/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java

Edit for question in comment:

You can add a javax.validation.MessageInterpolator to your javax.validation.Configuration to tell it to look for messages in other properties files. If you're using the Spring LocalValidatorFactory bean it has a setMessageInterpolator on it that you can use to inject one.

For hibernate, the provider implementation is: http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.html

This is a bit explanation of problem.

@Size(min = 1, max = 50, message = "Email size should be between 1 and 50")

Now remove { message = "Email size should be between 1 and 50" } from validation tag.

After doing this your annotation will be like this.

@Size(min = 1, max = 50)

Now at controller side debug the method which is being called upon when submitting the form. Below is my method which is receiving the request when user hits submit.

public static ModelAndView processCustomerLoginRequest(IUserService userService, LoginForm loginForm, 
    HttpServletRequest request, HttpSession session, BindingResult result, String viewType, Map<String, LoginForm> model)

Now place a debug point at very first line of the method and debug the argument "result".

BindingResult result

While dubugging you will find a string like this in codes array.

Size.loginForm.loginId

Now define this string in your properties file and a message against that string. Compile and execute. That message will be displayed whenever that annotation wouldn't be validated.

Size.loginForm.loginId=email shouldn't be empty.

Basically spring makes its own string as key to its property file message. In above key

Size(@Size) = validation annotation name
loginForm = My Class Name
loginId = Property name in LoginForm class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM