Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring mvc @ExceptionHandler method get same view

My problem is that I want to create an @ExceptionHandler method that will capture all un-handled exceptions. Once captured I would like to redirect to the current page instead of specifying a separate page just to display error.

Basically how do I get the value of someview returned by somemethod and set it dynamically in the method unhandledExceptionHandler below.

@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";
}

So in JSP I can render this error message back into the current page something like that.

<c:if test="${not empty UNHANDLED_ERROR}">
    <div class="messageError"> ${UNHANDLED_ERROR}</div>
</c:if>
like image 289
vincent Avatar asked Sep 16 '13 16:09

vincent


2 Answers

I dont think you can do this without modifying all of your handler methods. However you can try to do this in a "pretty" way:

1) You can define your own annotation which will accept target view name as a parameter (e.g. @ExceptionView)

2) Next thing to do is marking your handler methods with it, e.g.:

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

3) After that you can do something like this in exception handler:

@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;
}
like image 120
Leffchik Avatar answered Oct 22 '22 16:10

Leffchik


I have not tried this out, but based on the documentation here, we can get the request object in the exception handler. We may not be able to get the view linked to the URL. Getting the view from the URL, and the state/model of the view will be the tricky part.

  @ExceptionHandler(Exception.class)
  public ModelAndView handleError(HttpServletRequest req, Exception ex) {
    logger.error("Request: " + req.getRequestURL() + " raised " + ex);

    ModelAndView mav = new ModelAndView();
    mav.addObject("exception", ex);
    mav.addObject("url", req.getRequestURL());
    mav.setViewName("error");
    return mav;
  }
like image 45
asp Avatar answered Oct 22 '22 15:10

asp