开发者

Why is my Spring 3 Validator Validating Everything on the Model?

I have a spring 3 controller with a validator for one of the methods. It insists on validating every object on the model. Would anyone be able to explain to me why it does this or if I'm doing something wrong?

According to the docs, 5.7.4.3 Configuring a JSR-303 Validator for use by Spring MVC (http://static.springsource.org/spring/docs/3.0.0.RC3/spring-framework-reference/html/ch05s07.html)

With JSR-303, a single javax.validation.Validator instance typically validates all model objects that declare validation constraints. To configure a JSR-303-backed Validator with Spring MVC, simply add a JSR-303 Provider, such as Hibernate Validator, to your classpath. Spring MVC will detect it and automatically enable JSR-303 support across all Controllers.

Example:

@Controller
public class WhaleController {

        @Autowired
        private Validator myValidator;

        @Autowired
        private WhaleService whaleService;

        @InitBinder
        protected void initBinder(WebDataBinder binder) {
                binder.setValidator(this.myVal开发者_运维知识库idator);
        }

        @RequestMapping(value="/save-the-whales")
        @Transactional
        public void saveTheWhales(@Valid WhaleFormData formData, BindingResult errors, Model model) {
                if (!errors.hasFieldErrors()) {
                        Whale whale = new Whale();

                        whale.setBreed( formData.getBreed() );

                        this.whaleService.saveWhale( whale );

                        model.addAttribute("whale", whale);

                }
                model.addAttribute("errors", errors.getFieldErrors());
        }

}

When run it will complain that Whale is an invalid target for myValidator (which is set to validate WhaleFormData, and does so fine). Whale is a POJO with no validation constraints, annotation and no config anywhere. Through trial and error I've found that ANY object placed on the model will attempt to be validated and fail if the validator is not setup to handle it. Primitives are just fine.

Can anyone tell me why this is, point me to the appropriate documentation and/or tell me the best way to put something on the model without having it validated?

In the case above I would like to place "whale" on the model as it will now have a unique whaleId() that it received from my persistence layer.

Thanks!


I guess this behaviour is not covered in the documentation well.

The problem is caused by the following:

  1. By default, @InitBinder-annotated method is called for each non-primitive model attribute, both incoming and outcoming (the purpose of calling it for outcoming attibutes is to allow you to register custom PropertyEditors, which are used by form tags when rendering a form).

  2. DataBinder.setValidator() contains a defensive check that call Validator.supports() and throws an exception if false is returned. So, there is no attempt to perform a validation, just an early check.

The solution is to restrict the scope of @InitBinder to particular attribute:

@InitBinder("whaleFormData")
protected void initBinder(WebDataBinder binder) { ... }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜