Understanding "globalValidator" in Spring MVC

Xelian Source

I have custom validator and I register it in my controller

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new FooValidator());
    }

    @RequestMapping("/foo", method=RequestMethod.POST)
    public void processFoo(@Valid Foo foo) { ... }

}

but I want to register in other controllers also,so to be able just to write @Valid and the Foo object to be validated. From what I see I understand that I can use @ControllerAdviced class which to register the validator on every controller, or to use

 <mvc:annotation-driven validator="globalValidator"/>

But how to register my validator, how Spring understand which Validator I want to make global one? Scans for every implementing Validator class? Can I do it with xml configuration? How to use this approach?

I do not understand the Spring's description:

The alternative is to call setValidator(Validator) on the global WebBindingInitializer. This approach allows you to configure a Validator instance across all annotated controllers. This can be achieved by using the SpringMVC namespace:

xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xss http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<mvc:annotation-driven validator="globalValidator"/>
javaspringvalidationspring-mvc

Answers

answered 1 year ago dimitrisli #1

The documentation is quite clear on the Validation section:

In Spring MVC you can configure it for use as a global Validator instance, to be used whenever an @Valid or @Validated controller method argument is encountered, and/or as a local Validator within a controller through an @InitBinder method. Global and local validator instances can be combined to provide composite validation

If I understand correctly in your example the FooValidator you want to use it upon every validation as global Validator so define it as a bean and inject it as you show directly in the mvc:annotation-driven XML entry as you are showing already.

On top of that per-Controller you can have custom (applied on top only on that Controller-responsible forms) via the @InitBinder annotation.

As a side note, in your @RequestMapping method receiving the POST request where your @Valid parameter is: You can have a BindingResult entry right after that to take decisions on routes etc. In your example:

@RequestMapping("/foo", method=RequestMethod.POST)
public String processFoo(@Valid Foo foo, BindingResult result) {

   if(result.hasErrors()) {
      return "go/that/way";
   }
   //..
}

comments powered by Disqus