Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 296
Hoàng Long Avatar asked Apr 26 '11 06:04

Hoàng Long


People also ask

How do you validate properties in Spring boot?

However, to validate them we need to follow a couple of more steps. To have Spring Boot pick up our AppProperties class, we annotate our @Configuration class with @EnableConfigurationProperties : @Configuration @EnableConfigurationProperties(AppProperties. class) class AppConfiguration { // ... }

What is the use of @validated annotation?

@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. @Valid annotation on method parameters and fields to tell Spring that we want a method parameter or field to be validated.

Can we create custom annotation for validation?

In this way, we can create different custom annotations for validation purposes. You can find the full source code here. It is easy to create and use custom annotations in Java. Java developers will be relieved of redundant code by using custom annotations.


2 Answers

To tell Hibernate validator to do a lookup on a code, put the value of message in braces, e.g., @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 the 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. You can read the implementation here.

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. Check this source for the Hiberate provider implementation.

like image 177
Affe Avatar answered Nov 07 '22 11:11

Affe


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.
like image 28
Shan Arshad Avatar answered Nov 07 '22 11:11

Shan Arshad