Spring ExceptionHandler访问Model?

时间:2014-01-22 14:04:55

标签: spring-mvc exception-handling

我有一个spring控制器,它使用bean验证来验证输入值,例如保存主题:

public String save(@ModelAttribute("topic") @Valid Topic topic

这很好用。

在我的数据层中,我也使用bean验证,当一些无效的东西发送到数据层时,抛出了ConstraintViolationException。我在控制器中用异常处理程序捕获了这个:

@ExceptionHandler({ ConstraintViolationException.class })
public ModelAndView  handleValidationException(HttpServletRequest req,ConstraintViolationException e) {

这也很有效。

我面临的问题是我无法访问我的异常处理程序中的模型,文档清楚地说明了这一点:

Important Note: the Model may not be a parameter of any @ExceptionHandler method.

需要访问模型,因为我想向用户显示他刚填写的表单的视图。但由于我无法访问模型,因此无法获得填写的表单数据。

我找到的一个解决方案是在我的save()方法中捕获ConstraintViolationException,因为这里我可以访问模型。

但是当我需要将某些东西保存到数据库时,我更喜欢通用解决方案并且没有凌乱的try / catch / finally。

有人知道一个好的解决方案吗?

[编辑] 这是我当前的异常处理程序:

@ExceptionHandler({ ConstraintViolationException.class })
public ModelAndView  handleValidationException(HttpServletRequest req,ConstraintViolationException e) {
log.debug("handleValidationException");

//no access to model, so i create new one, but this new one doesn't have the values the user entered in the html form.

ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.setViewName("add_topc");
return mav;
}

2 个答案:

答案 0 :(得分:0)

在对这个主题进行一些思考之后,我得出结论,显示错误的单个错误页面就足够了。主要是因为数据层抛出的错误是用户无法纠正的致命错误,例如通过更改字段值。当然,在出现问题的情况下显示错误页面并保存用户输入会很不错。但春天似乎不太可能。

答案 1 :(得分:0)

有点老但我发现自己处于类似情况。

一种可能的解决方案是将模型包装在contraintViolationException中,以便异常处理程序可以从异常中提取模型。

我没有找到任何关于为什么模型在异常处理程序中被清除/不可用的良好解释 - 除非有人假设它是设计的,因为模型可能处于无效状态。

来自Controller的

SNIPET

...  
throw new ConstraintViolationException(model);
来自ModelAwareException的

SNIPET

public void ConstraintViolationException(Model saveModel)  {
    this.model = saveModel;
}
来自ExceptionHandler的

SNIPET

@ExceptionHandler({ ConstraintViolationException.class })
public ModelAndView  handleValidationException(HttpServletRequest req,ConstraintViolationException e, Model unpopulatedSpringModel) {

    unpopulatedSpringModel = e.getModel();
    return new ModelAndView("yourpage");

}