Выполнение перенаправления из метода spring MVC @ExceptionHandler

Я хочу иметь следующий метод:

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

Я получаю:

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

Есть ли способ выполнить перенаправление с @ExceptionHandler? Или, может быть, какой-то способ обойти это ограничение?

EDIT:

Я изменил свой обработчик исключений следующим образом:

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

Это метод, который может вызывать исключение:

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

Проблема с моим модифицированным обработчиком исключений заключается в том, что систематически перенаправляет меня на следующий URL-адрес:

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

Вместо:

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

РЕДАКТИРОВАТЬ 2:

Вот мой модифицированный метод обработчика:

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

Теперь проблема заключается в том, что сообщение застряло в сеансе...

Ответ 1

Обратите внимание, что на самом деле это поддерживается с помощью Spring 4.3.5+ (см. SPR-14651 для более подробно).

Мне удалось заставить его работать с использованием класса RequestContextUtils. Мой код выглядит следующим образом:

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

Затем на странице jsp я просто получаю доступ к атрибуту

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

Надеюсь, что это поможет!

Ответ 2

Вы всегда можете переслать, а затем перенаправить (или перенаправить дважды). Сначала к другому сопоставлению запроса, где у вас есть нормальный доступ к RedirectAttributes, а затем снова к вашему окончательному пункту назначения.

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

Ответ 3

Я смотрю JavaDoc, и я не вижу, где RedirectAttributes является допустимым типом, который принят.

Ответ 4

Начиная с Spring 4.3.5 (SPR-14651) вы можете сразу использовать свой первый подход:

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