Announcement Announcement Module
Collapse
No announcement yet.
RedirectInterceptor for transparent redirects Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • RedirectInterceptor for transparent redirects

    "redirect after post" is a common pattern. But if you want to pass a rich model to your view (more than URL parameters), you have to save the model in the session. Thus your controller has to know whether it is redirecting or just forwarding to a view. I created a RedirectInterceptor and RedirectViewController to make this transparent for the controller :

    Code:
    public class RedirectInterceptor extends HandlerInterceptorAdapter {
    
      protected final Log logger = LogFactory.getLog(getClass());
      private static final String PREFIX = "redirect:";
      private static final String SUFFIX = ".htm";
    
      public void postHandle(HttpServletRequest request, HttpServletResponse response,
          Object handler, ModelAndView modelAndView) throws Exception {
        String viewName = modelAndView.getViewName();
        if (viewName != null && viewName.startsWith(PREFIX) && !viewName.endsWith(SUFFIX)) {
          logger.debug("putting MODEL and VIEW in session");
          Map model = modelAndView.getModel();
          request.getSession().setAttribute(RedirectViewController.KEY_MODEL, model);
          request.getSession().setAttribute(RedirectViewController.KEY_VIEW_NAME, viewName.substring(PREFIX.length()));
          modelAndView.clear();
          modelAndView.setViewName("redirect:Redirect.htm");
        }
      }
    
    }
    "Redirect.htm" is mapped to the RedirectViewController :

    Code:
    public class RedirectViewController implements Controller {
    
      static final String KEY_MODEL = "RedirectViewController.MODEL";
      static final String KEY_VIEW_NAME = "RedirectViewController.VIEW_NAME";
    
      protected final Log logger = LogFactory.getLog(getClass());
    
      public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("getting MODEL and VIEW from session");
        HttpSession session = request.getSession();
        Map model = (Map) session.getAttribute(KEY_MODEL);
        String viewName = (String) session.getAttribute(KEY_VIEW_NAME);
        logger.debug("viewName = " + viewName);
        return new ModelAndView(viewName, model);
      }
    }
    This way I can inject the viewName into my controller, and controller
    doesn't need to know it is redirecting.

    1) controller handles request
    2) interceptor saves model and viewName in the session
    3) browser is redirected to Redirect.htm => RedirectViewController
    4) RedirectViewController restores model and forwards to original view

    My solution works, but since it seems like a common pattern, I wondered if Spring already has a (better) mechanism for this behaviour ?

    Maarten

  • #2
    No, support like this isn't available in Spring at the moment. Of course there are the redirect: and forward: prefixes, but it seems you've figured those out already. I think it might be a good addition!

    Could you create a JIRA issue for this (please set the 'fix in release' value to 1.3 since this will not make 1.2 anymore unfortunately).

    regards,
    Alef Arendsen

    Comment


    • #3
      Hello,

      Maarten: thanks for sharing the code for the RedirectInterceptor.

      Just wondered if there was a similarly clean solution that could be applied when using the SimpleFormController. When validation errors occur the form page is displayed again - but since no redirect is done prior to it being displayed, this causes problems.

      Thanks

      jv

      Comment

      Working...
      X