Давайте напишем следующее
public class Person {
private String name;
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
И ваш MultiActionController
import static org.springframework.validation.ValidationUtils.*;
@Component
public class PersonController extends MultiActionController {
public PersonController() {
setMethodNameResolver(new InternalPathMethodNameResolver());
setValidators(new Validator[] {new Validator() {
public boolean supports(Class clazz) {
return clazz.isAssignableFrom(Person.class);
}
public void validate(Object command, Errors errors) {
rejectIfEmpty(errors, "age", "", "Age is required");
rejectIfEmptyOrWhitespace(errors, "name", "", "Name is required");
}
}});
}
public ModelAndView add(HttpServletRequest request, HttpServletResponse response, Person person) throws Exception {
// do something (save our Person object, for instance)
return new ModelAndView();
}
}
MultiActionController определяет свойство, называемое validators , где вы должны предоставить любой Validator , используемый вашим MultiActionController . Здесь вы можете увидеть фрагмент кода, который отвечает за проверку вашего объекта Command внутри MultiActionController
ServletRequestDataBinder binder = ...
if (this.validators != null)
for (int i = 0; i < this.validators.length; i++) {
if (this.validators[i].supports(command.getClass())) {
ValidationUtils.invokeValidator(this.validators[i], command, binder.getBindingResult());
}
}
}
/**
* Notice closeNoCatch method
*/
binder.closeNoCatch();
closeNoCatch метод говорит
Обрабатывает ошибки как фатальные
Таким образом, если ваш Validator возвращает какую-либо ошибку, closeNoCatch выдаст ServletRequestBindingException . Но , вы можете перехватить его внутри вашего метода MultiActionController, как показано ниже
public ModelAndView hanldeBindException(HttpServletRequest request, HttpServletResponse response, ServletRequestBindingException bindingException) {
// do what you want right here
BindException bindException = (BindException) bindingException.getRootCause();
return new ModelAndView("personValidatorView").addAllObjects(bindException.getModel());
}
Для тестирования давайте сделаем следующее
@Test
public void failureValidation() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.setRequestURI("http://127.0.0.1:8080/myContext/person/add.html");
/**
* Empty values
*/
request.addParameter("name", "");
request.addParameter("age", "");
PersonController personController = new PersonController();
ModelAndView mav = personController.handleRequest(request, new MockHttpServletResponse());
BindingResult bindingResult = (BindingResult) mav.getModel().get(BindingResult.MODEL_KEY_PREFIX + "command");
/**
* Our Validator rejected 2 Error
*/
assertTrue(bindingResult.getErrorCount() == 2);
for (Object object : bindingResult.getAllErrors()) {
if(object instanceof FieldError) {
FieldError fieldError = (FieldError) object;
System.out.println(fieldError.getField());
}
}
}