Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding multiple validators using initBinder

I'm adding a user validator using the initBinder method:

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

Here is the UserValidator

public class UserValidator implements Validator {      public boolean supports(Class clazz) {         return User.class.equals(clazz);     }      public void validate(Object target, Errors errors) {         User u = (User) target;          // more code here     } } 

The validate method is getting properly called during the controller method call.

@RequestMapping(value = "/makePayment", method = RequestMethod.POST) public String saveUserInformation(@Valid User user, BindingResult result, Model model){      // saving User here      // Preparing CustomerPayment object for the payment page.     CustomerPayment customerPayment = new CustomerPayment();     customerPayment.setPackageTb(packageTb);     model.addAttribute(customerPayment);     logger.debug("Redirecting to Payment page.");      return "registration/payment"; } 

But while returning to the payment screen I'm getting this error:

java.lang.IllegalStateException: Invalid target for Validator [com.validator.UserValidator@710db357]: com.domain.CustomerPayment[ customerPaymentId=null ] org.springframework.validation.DataBinder.setValidator(DataBinder.java:476) com.web.UserRegistrationController.initBinder(UserRegistrationController.java:43) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.initBinder(HandlerMethodInvoker.java:393) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.updateModelAttributes(HandlerMethodInvoker.java:222) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:429) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)

This might be because I'm returning a CustomerPayment and there is not validator defined for that.

I'm also not able to add multiple validators in initBinder method.

How can I fix this?

like image 987
Ravi Avatar asked Jan 26 '13 03:01

Ravi


2 Answers

You need to set the value of the @InitBinder annotation to the name of the command you want it to validate. This tells Spring what to apply the binder to; without it, Spring will try to apply it to everything. This is why you're seeing that exception: Spring is trying to apply the binder - with your UserValidator - to a parameter of type CustomerPayment.

In your specific case, it looks like you need something like:

@InitBinder("user") protected void initBinder(WebDataBinder binder) {     binder.setValidator(new UserValidator()); } 

To your second question, as Rigg802 explained, Spring does not support attaching multiple validators to a single command. You can, however, define multiple @InitBinder methods for different commands. So, for example, you could put the following in a single controller and validate your user and payment parameters:

@InitBinder("user") protected void initUserBinder(WebDataBinder binder) {     binder.setValidator(new UserValidator()); }  @InitBinder("payment") protected void initPaymentBinder(WebDataBinder binder) {     binder.setValidator(new CustomerPaymentValidator()); } 
like image 177
Annabelle Avatar answered Sep 29 '22 07:09

Annabelle


It's a bit tricky to do, 1 controller has only 1 validator on 1 command object. you need to create a "Composite Validator" that will get all the validators and run them seperately.

Here is a tutorial that explains how to do it: using multiple validators

like image 29
Rigg802 Avatar answered Sep 29 '22 05:09

Rigg802