spring-mvcpost-redirect-get

Performing a redirect from a spring MVC @ExceptionHandler method


I want to have the following method:

@ExceptionHandler(MyRuntimeException.class)
public String myRuntimeException(MyRuntimeException e, RedirectAttributes redirectAttrs){//does not work
    redirectAttrs.addFlashAttribute("error", e);
    return "redirect:someView";
}

I get a:

java.lang.IllegalStateException: No suitable resolver for argument [1] type=org.springframework.web.servlet.mvc.support.RedirectAttributes]

Is there a way to perform a redirect from an @ExceptionHandler? Or maybe some way to circumvent this restriction?

EDIT:

I have modified my exception handler as follows:

@ExceptionHandler(InvalidTokenException.class)
public ModelAndView invalidTokenException(InvalidTokenException e, HttpServletRequest request) {
RedirectView redirectView = new RedirectView("signin");
return new ModelAndView(redirectView , "message", "invalid token/member not found");//TODO:i18n
}

This is the method that may throw the exception:

@RequestMapping(value = "/activateMember/{token}", method = RequestMethod.GET, produces = "text/html")
public String activateMember(@PathVariable("token") String token) {
    signupService.activateMember(token);
    return "redirect:memberArea/index";
}

The problem with my modified exception handler is that it systematically redirects me to the following URL:

http://localhost:8080/bignibou/activateMember/signin?message=invalid+token%2Fmember+not+found 

Instead of:

http://localhost:8080/bignibou/signin?message=invalid+token%2Fmember+not+found

EDIT 2:

Here is my modified handler method:

@ExceptionHandler(InvalidTokenException.class)
public String invalidTokenException(InvalidTokenException e, HttpSession session) {
session.setAttribute("message", "invalid token/member not found");// TODO:i18n
return "redirect:../signin";
}

The problem I now have is that the message is stuck in the session...


Solution

  • Note that this is actually supported out-of-the-box by Spring 4.3.5+ (see SPR-14651 for more details).

    I've managed to get it working using the RequestContextUtils class. My code looks like this

    @ExceptionHandler(MyException.class)
    public RedirectView handleMyException(MyException ex,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws IOException {
        String redirect = getRedirectUrl(currentHomepageId);
    
        RedirectView rw = new RedirectView(redirect);
        rw.setStatusCode(HttpStatus.MOVED_PERMANENTLY); // you might not need this
        FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
        if (outputFlashMap != null){
            outputFlashMap.put("myAttribute", true);
        }
        return rw;
    }
    

    Then in the jsp page I simply access the attribute

    <c:if test="${myAttribute}">
        <script type="text/javascript">
          // other stuff here
        </script>
    </c:if>
    

    Hope it helps!