为什么BindingResult必须关注@Valid?

时间:2015-03-05 21:10:56

标签: java spring validation spring-mvc

当我遇到错误时,我很难让我的Spring MVC验证返回页面提交页面。我终于解决了这个问题,注意到BindingResult需要在我正在验证的表单参数旁边。

例如,如果我将spring.io教程(http://spring.io/guides/gs/validating-form-input/)中的checkPersonInfo方法修改为 -

@RequestMapping(value="/", method=RequestMethod.POST)
public String checkPersonInfo(@Valid Person person, BindingResult bindingResult, Model model) {
    if (bindingResult.hasErrors()) {
        return "form";
    }
    return "redirect:/results";
}

然后它将工作并重定向到表单页面,但如果我将其更改为 -

@RequestMapping(value="/", method=RequestMethod.POST)
public String checkPersonInfo(@Valid Person person, Model model, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return "form";
    }
    return "redirect:/results";
}

然后重定向到/ errors

这是什么原因?

3 个答案:

答案 0 :(得分:11)

BindingResult必须遵循绑定的对象。原因是如果你有更多被绑定的对象,你必须知道哪个BindingResult属于哪个对象。

答案 1 :(得分:3)

您的请求处理程序中可能有多个模型属性,每个属性都有自己的绑定结果。为了适应这种情况,Spring决定将绑定结果参数绑定到前一个参数。

答案 2 :(得分:3)

是的,今天我花了很长时间检查为什么不能回到提交的页面但是转到默认的whitelable错误页面。

调试后获得源代码

// org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
    throw new BindException(binder.getBindingResult());
}

如果BindingResult不遵循@Valid,则导致isBindExceptionRequired(binder, parameter)返回true,然后直接抛出异常,因此无法在控制器方法中执行代码。

// org.springframework.web.method.annotation.ModelAttributeMethodProcessor#isBindExceptionRequired 
protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter methodParam) {
    int i = methodParam.getParameterIndex();
    Class<?>[] paramTypes = methodParam.getMethod().getParameterTypes();
    boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
    return !hasBindingResult;
}