Announcement Announcement Module
Collapse
No announcement yet.
HandlerInterceptor and redirect problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • HandlerInterceptor and redirect problem

    Hello,

    I need to show dates/times in the end user's time zone although internally they're stored in UTC. This means that the business object that I present to the JSP has attributes in UTC. In each controller I was adding an attribute to the model for the user's timeZoneId and then the JSP view would output the date/time for that timeZoneId. I figured augmenting the model with the timeZoneId was the sort of thing much better suited to a HandlerInterceptor.

    The intercept code is probably unnecessary but here it is anyway:
    Code:
    public class TimeZoneIdInterceptor implements HandlerInterceptor {
    
        private final static String MODEL_ATTR_NAME_TIME_ZONE_ID = "timeZoneId";
    
        String defaultTimeZoneId;
    
        @Autowired
        public TimeZoneIdInterceptor(String defaultTimeZoneId) {
            this.defaultTimeZoneId = defaultTimeZoneId;
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            // Put the user's time zone id into the model
            if(modelAndView != null) {
                String userTimeZoneId = SecurityUtils.getUserTimeZoneId();
                modelAndView.getModel().put(MODEL_ATTR_NAME_TIME_ZONE_ID, userTimeZoneId != null ? userTimeZoneId : defaultTimeZoneId);
            }
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        }
    }
    The problem I'm getting is if my controller has a POST request and then does a redirect. The redirect URL has the timeZoneId and value appended to it. For instance, I return a view of
    Code:
    "redirect:/app/job/1"
    and the actual redirect URL is
    Code:
    /app/job/1?timeZoneId=Europe%2FLondon
    How can I get rid of this attribute from the model on redirects? HandlerInterceptor.afterCompletion() doesn't help (from what I could tell in the debugger) as the redirect request has already been composed.

    I could add statements to the POST handler in the controller to clear the model map, but if I'm going to do that, I might as well go back to what I was doing before and remove the interceptor altogether and add the timeZoneId manually to the model.

    Thanks for reading,

    PUK

    P.S. This is not the first time that the policy of exporting the model to a redirect has caused me problems. See http://forum.springsource.org/showpo...92&postcount=9. I can't understand the rationale behind it

  • #2
    Originally posted by PUK_999 View Post
    I could add statements to the POST handler in the controller to clear the model map
    I don't think I can do this because the controller is invoked before HandlerInterceptor.postHandle()

    PUK

    Comment


    • #3
      There are at least three solutions to your problem:
      1. Put the user's time zone id into the session instead of the model. Do you expect it to change between requests?
      2. Write your own redirect view (including a view resolver) that filters out properties you don't want to see in the URL
      3. Use a different redirect mechanism (shameless plug: http://forum.springsource.org/showpo...8&postcount=11)

      Just my 0.02

      Comment


      • #4
        The timeZoneId will remain constant for their session so I will pursue your first suggestion. Thanks for the menu of choices and the speedy reply!

        Back to the redirect thing: Is it just me, or is the exposing of the model to the redirect a big pain for little or no benefit? It's not as if all the model gets exposed anyway - only the trivial types that can be easily textualised. It complicates POST handlers and narrows the cases where HandlerInterceptors can be used. Wondering if I should create a JIRA but want to ensure I'm not missing the benefit of it.

        PUK

        Comment


        • #5
          Originally posted by PUK_999 View Post
          Back to the redirect thing: Is it just me, or is the exposing of the model to the redirect a big pain for little or no benefit? It's not as if all the model gets exposed anyway - only the trivial types that can be easily textualised. It complicates POST handlers and narrows the cases where HandlerInterceptors can be used. Wondering if I should create a JIRA but want to ensure I'm not missing the benefit of it.
          I created https://jira.springsource.org/browse/SPR-6796 as I'd love to be able to redirect simply without exposing the model to the redirected URL. If you would too, please vote.

          PUK

          Comment


          • #6
            If you are using an org.springframework.web.servlet.view.RedirectView to do the redirect, you can avoid the additional parameters by setting exposeModelAttributes to false.

            This is what my interceptor does in postHandle for redirecting:

            private void doRedirect( HttpServletResponse response, String targetUrl, ModelAndView modelAndView ) throws IOException {
            if ( modelAndView != null ) {
            RedirectView rView = new RedirectView(targetUrl, true);
            rView.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
            rView.setHttp10Compatible(false);
            rView.setExposeModelAttributes(false);
            modelAndView.setView(rView);
            }
            response.sendRedirect(targetUrl);
            }

            Comment


            • #7
              Simply don't add your objects to the model when the view is a redirect.

              Code:
                  @Override
                  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                      if(modelAndView != null && !modelAndView.getViewName().startsWith("redirect:")) {
                          String userTimeZoneId = SecurityUtils.getUserTimeZoneId();
                          modelAndView.getModel().put(MODEL_ATTR_NAME_TIME_ZONE_ID, userTimeZoneId != null ? userTimeZoneId : defaultTimeZoneId);
                      }
                  }

              Comment

              Working...
              X