Как проверить несколько POJO с помощью весеннего валидатора?

У меня есть одна форма, для которой есть три Pojo, потому что есть три отдельных таблицы, по одной для каждого Pojo. Два поля в форме предварительно заполнены. Теперь я хочу проверить форму с помощью весеннего валидатора. Я пытался использовать абстрактный класс с общими полями всех трех Pojo в нем, и каждый Pojo расширял его, но Spring не смог создать объект для абстрактного класса и выдал исключение. Я предпочитаю не использовать интерфейс, так как мне нужно инициализировать все поля.

Ниже приведен код ссылки.

Контроллер

@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";

    }
}

Валидатор

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...
     }
   }
 }

Кроме того, последний Pojo, то есть test, похоже, перекрывает два других с сообщением об ошибке.


person Hello World    schedule 13.09.2018    source источник
comment
Пожалуйста, предоставьте структуру вашего класса POJO, а также покажите полную трассировку стека сообщенной ошибки.   -  person Javad Alimohammadi    schedule 14.09.2018
comment
@ Джавад Алимохаммади: Что общего со структурой Pojo?   -  person Hello World    schedule 17.09.2018
comment
Что ж, некоторые ответы подталкивают пользователя OP к цели, но не являются полными. создание модели-обертки - хорошая идея. но после его создания вы должны использовать аннотацию @Valid для каждой модели в модели-оболочке. похоже на это: public class WrapperModel { @Valid private Foo foo; @Valid private Bar bar; // ...}   -  person Hadi J    schedule 22.09.2018


Ответы (2)


В вашем контроллере вам нужно инициализировать валидатор через биндер.

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

Вы также должны поместить BindingResult после модели, которую вы хотите проверить.

«Параметры Errors или BindingResult должны следовать за объектом модели, который привязывается немедленно, поскольку сигнатура метода может иметь более одного объекта модели, и Spring создаст отдельный BindingResult» — из документов Spring.

Так и должно было быть в вашем случае.

@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";

    }
}
person Jade Devin Nocum Cabatlao    schedule 22.09.2018
comment
но вопрос заключался в проверке нескольких pojo! - person MohammadReza Alagheband; 22.09.2018
comment
@MohammadRezaAlagheband Обновил мой ответ, чтобы прояснить его. - person Jade Devin Nocum Cabatlao; 22.09.2018
comment
@JadeDevinNocumCabatlao: Мой вопрос заключался в том, какое Pojo будет передано в метод проверки в качестве аргумента. - person Hello World; 24.09.2018

Один ответ, описанный в , применяет пользовательский валидатор в Spring MVC-контроллер более чем в одном классе, если это не поможет, вы можете пойти со следующим ответом.

Наличие другой модели/PoJo для проверки не является хорошей идеей в spring mvc, я могу предложить создать класс-оболочку, который включает в себя оба класса, и проверить его как один класс.

Представьте, что у вас есть:

class MyClass1 {
    // codes
}

class MyClass2 {
    // codes
}

Вы должны создать:

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

теперь легко проверить этот единственный класс-оболочку.

person MohammadReza Alagheband    schedule 22.09.2018