Вопрос

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...

Это было полезно?

Решение

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!

Другие советы

You could always forward then redirect (or redirect twice).. First to another request mapping where you have normal access to RedirectAttributes, then again to your final destination.

    @ExceptionHandler(Exception.class)
    public String handleException(final Exception e) {

        return "forward:/n/error";
    }

    @RequestMapping(value = "/n/error", method = RequestMethod.GET)
    public String error(final RedirectAttributes redirectAttributes) {

        redirectAttributes.addAttribute("foo", "baz");
        return "redirect:/final-destination";
    }

I am looking at the JavaDoc and I don't see where RedirectAttributes is a valid type that is accepted.

Since Spring 4.3.5 (SPR-14651) you can use stright away your first aproach:

@ExceptionHandler(MyRuntimeException.class)
public String myRuntimeException(MyRuntimeException e, RedirectAttributes redirectAttrs){
    redirectAttrs.addFlashAttribute("error", e);
    return "redirect:someView";
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top