bas*_*ode 17 exception-handling spring-mvc
我正在尝试对记录异常的代码进行分组,并在一些方法中呈现一个漂亮的视图.目前,逻辑在@RequestHandler自身的某个时刻(在一个catch块中),其他任务被委托给一个实用程序类(它可以工作,但会将逻辑从抛出异常的地方移开).
Spring @ExceptionHandler似乎是将所有内容组合在一个地方(控制器本身或父级)并摆脱一些代码(不需要在try-catch中放置逻辑而不需要实用程序类)的方法......直到我意识到一种@ExceptionHandler方法不会有ModelMap或BindingResult自动装配参数.目前,这些对象用于使用合理的错误消息呈现视图,并且我们还想记录这些对象中包含的一些信息.
为什么Spring不支持这样的方法参数ModelMap或者BindingResult用于@ExceptionHandler?它背后的理由是什么?
在Spring源代码(3.0.5)中,该方法的参数在HandlerMethodInvoker.invokeHandlerMethod.请求处理程序抛出的异常会被捕获并重新抛出.它@ExceptionHandler和它的参数在其他地方得到解决.作为一种解决方法,我想检查Exception是否实现了一个假设的"ModelAware"或"BindingResultAware"接口,在这种情况下,在重新抛出之前设置Model和BindingResult属性.听起来怎么样?
小智 5
如前所述,您可以在控制器的某些方法中引发包装绑定结果对象的异常:
if (bindingResult.hasErrors()) {
logBindingErrors(bindingResult);
//return "users/create";
// Exception handling happens later in this controller
throw new BindingErrorsException("MVC binding errors", userForm, bindingResult);
}
Run Code Online (Sandbox Code Playgroud)
您的异常定义如下所示:
public class BindingErrorsException extends RuntimeException {
private static final Logger log = LoggerFactory.getLogger(BindingErrorsException.class);
private static final long serialVersionUID = -7882202987868263849L;
private final UserForm userForm;
private final BindingResult bindingResult;
public BindingErrorsException(
final String message,
final UserForm userForm,
final BindingResult bindingResult
) {
super(message);
this.userForm = userForm;
this.bindingResult = bindingResult;
log.error(getLocalizedMessage());
}
public UserForm getUserForm() {
return userForm;
}
public BindingResult getBindingResult() {
return bindingResult;
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,您只需从引发然后捕获的异常中提取所需的信息。这里假设您在控制器上定义了一个合适的异常处理程序。它可能在控制器建议中,甚至在其他地方。有关合适的位置,请参阅 Spring 文档。
@ExceptionHandler(BindingErrorsException.class)
public ModelAndView bindingErrors(
final HttpServletResponse resp,
final Exception ex
) {
if(ex instanceof BindingErrorsException) {
final BindingErrorsException bex = (BindingErrorsException) ex;
final ModelAndView mav = new ModelAndView("users/create", bex.getBindingResult().getModel());
mav.addObject("user", bex.getUserForm());
return mav;
} else {
final ModelAndView mav = new ModelAndView("users/create");
return mav;
}
}
Run Code Online (Sandbox Code Playgroud)
我不久前遇到了同样的问题。的 JavaDocs 中明确未将ModelMap或列为受支持的参数类型,因此这肯定是有意为之。BindingResult@ExceptionHandler
我认为其背后的原因是,一般抛出异常可能会使您ModelMap处于不一致的状态。所以根据你的情况你可以考虑
BindingResult给异常并稍后从异常中提取以用于渲染目的BeanValidation示例一样)华泰
| 归档时间: |
|
| 查看次数: |
7715 次 |
| 最近记录: |