spring mvc @ExceptionHandler方法得到相同的视图

时间:2013-09-16 16:11:57

标签: java spring spring-mvc exceptionhandler

我的问题是我想创建一个@ExceptionHandler方法来捕获所有未处理的异常。一旦捕获,我想重定向到当前页面而不是指定一个单独的页面只是为了显示错误。

基本上我如何获得 somemethod 返回的 someview 的值,并在下面的方法 unhandledExceptionHandler 中动态设置它。

@ExceptionHandler(Exception.class)
protected ModelAndView unhandledExceptionHandler(Exception ex){
    System.out.println("unhandle exception here!!!");
    ModelAndView mv = new ModelAndView();
    mv.setViewName("currentview");
    mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT. "+ex.getMessage());
    return mv;
}



@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(HttpSession session) throws Exception {
    String abc = null;
    abc.length();
    return "someview";
}

因此在JSP中我可以将此错误消息呈现回当前页面。

<c:if test="${not empty UNHANDLED_ERROR}">
    <div class="messageError"> ${UNHANDLED_ERROR}</div>
</c:if>

5 个答案:

答案 0 :(得分:6)

我认为没有办法做你要求的事情,因为在异常处理程序方法unhandledExceptionHandler中,没有办法找出处理程序方法{{1的视图名称会回来的。

唯一的方法是引入某种元数据方案,这样当你最终进入异常处理程序时,你可以找出将它映射到的视图。但我认为这种元数据方案会相当复杂。您可以通过查找抛出异常时正在访问的原始URL来实现此类方案,这可以通过下面的代码片段来完成。

somemethod

一旦你知道你可以重定向到它的原始请求URL,可能使用flash属性来存储有异常的事实以及错误是什么。

如果您有一个在不同视图之间进行选择的处理程序方法,则会出现元数据的主要问题。

(ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()

即使知道某些方法是错误的来源,您也不知道if语句中的哪个分支导致了异常。

答案 1 :(得分:5)

我不认为你可以在不修改所有处理程序方法的情况下做到这一点。但是你可以尝试在&#34;漂亮的&#34;方式:

1)您可以定义自己的注释,将目标视图名称作为参数接受(例如@ExceptionView

2)接下来要做的就是用它来标记你的处理程序方法,例如:

@ExceptionView("someview")
@RequestMapping(value = "/somepage", method = RequestMethod.GET)
    public String somemethod(HttpSession session) throws Exception {
    String abc = null;
    abc.length();
    return "someview";
}

3)之后你可以在异常处理程序中执行类似的操作:

@ExceptionHandler(Exception.class)
protected ModelAndView unhandledExceptionHandler(Exception ex, HandlerMethod hm) {
    String targetView;
    if (hm != null && hm.hasMethodAnnotation(ExceptionView.class)) {
        targetView = hm.getMethodAnnotation(ExceptionView.class).getValue();
    } else {
        targetView = "someRedirectView"; // kind of a fallback
    }
    ModelAndView mv = new ModelAndView();
    mv.setViewName(targetView);
    mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT. "+ex.getMessage());
    return mv;
}

答案 2 :(得分:2)

您可以将错误放在ModelAndView对象中,而不是在单独的页面上发送错误。在您的情况下,您可以将try / catch放在控制器方法中并返回相同的视图:

@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(ModelAndView mv,HttpSession session) throws Exception {
   mv.setViewName("someview");
   try{ 
      String abc = null;
      abc.length();
    } catch(Exception e) {
      mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT.  "+ex.getMessage());
   }
   return mv;
}

所以将ModelAndView添加到您的方法并返回它。

答案 3 :(得分:2)

我没有尝试过,但根据文档here,我们可以在异常处理程序中获取请求对象。我们可能无法将视图链接到URL。从URL获取视图,以及视图的状态/模型将是棘手的部分。

    File file = new File(filename);
    file.delete();

答案 4 :(得分:0)

  1. 创建使用@RequestMethod("/server-error")
  2. 注释的控制器方法
  3. 创建一个用@ExceptionHandler注释的控制器方法return "forward:/server-error";