Hello World
Hello World

Reputation: 983

How to validate multiple POJO using spring validator?

I have a single form for which there are three Pojo, because there are three separate tables one for each Pojo. Two fields in the form are pre populated. Now I want to validate the form using spring validator. I tried to use an abstract class with common fields of all three Pojo in it and each Pojo extending it but spring failed to create Object for abstract class and throws an exception. I prefer not to go with Interface since I have to initialize all the fields.

Below is the reference code.

Controller

@RequestMapping(value="/save",method=RequestMethod.POST)
public String saveData(@ModelAttribute("commonForm")@Valid Foo foo,FooBar fooBar,Test test,BindingResult result){

    this.testValidator.validate(foo, result); //which Pojo to provide here
    if(result.hasErrors()){
        return "redirect:/regPage";
    }else{
        return "success";

    }
}

Validator

public class TestValidator implements Validator{

@Override
public boolean supports(Class<?> clazz) {

    return Foo.class.equals(clazz)|| FooBar.class.equals(clazz)|| Test.class.equals(clazz);
}


@Override
public void validate(Object target, Errors errors) {

    if(target instanceof Foo){

        //validate Foo...

    }else if(target instanceof FooBar){

        //validate FooBar...
    }else{

        //validate Test...
     }
   }
 }

Also the last Pojo i.e. test seems to be overlapping the other two with error message.

Upvotes: 2

Views: 2429

Answers (2)

Mohammadreza  Alagheband
Mohammadreza Alagheband

Reputation: 2230

One answer described in apply custom validator in spring MVC controller in more than one class if that does not help you can go with the following answer.

Having Different Model/PoJo to validate is not a good idea in spring mvc,what i can suggest is to create a wrapper class that includes both classes and the validate it like a single class.

Imagine you have:

class MyClass1 {
    // codes
}

class MyClass2 {
    // codes
}

You should create:

class WrapperClass {
    private Class1 class1;
    private Class2 class2;
    // getter & setters
}

now it's easy to validate this single wrapper class.

Upvotes: 0

In your controller, you need to initialize the validator through the binder.

@InitBinder
public void InitBinder(WebdataBinder binder){
 binder.addValidators(new TestValidator())
}

You also have to place the BindingResult after the Model that you want to validate.

"The Errors or BindingResult parameters have to follow the model object that is being bound immediately as the method signature might have more that one model object and Spring will create a separate BindingResult" - From Spring docs

So in your case, it should have been.

@RequestMapping(value="/save",method=RequestMethod.POST)
public String saveData(@ModelAttribute("commonForm")@Valid Foo foo, BindingResult resultFoo, @Valid FooBar fooBar, BindingResult resultFooBar, @Valid Test test, BindingResult resultTest){

    if(resultFoo.hasErrors() || resultFooBar.hasErrors() || resultTest.hasErrors()){
        return "redirect:/regPage";
    }else{
        return "success";

    }
}

Upvotes: 1

Related Questions