Details

    • Type: New Feature
    • Status: Resolved
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Web
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      Introduce @HandlerInterceptor to create a more symmetrical relationship between @Controller, @ModelAttribute and @RequestParam.

      This came out of some questions and brainstorming in a Spring training session in LA, 5/1/08 with Chris Beams, Tchavdar Ivanov (FIM) and myself.

      In Spring 2.5 the implementation of HandlerInterceptor has not changed leaving you to either implement the interface or extend HandlerInterceptorAdapter as before. If you use @Controller and component scan you still must define a DefaultAnnotationHandlerMapping to configure a single list of HandlerInterceptors for all Controllers.

      It'd be nice if you could define a class as a @HandlerInterceptor and annotate methods as @AfterCompletion, @PreHandle and @PostHandle. The default behavior could automagically intercept all @Controllers scanned and fire according to the same contract as the original HandlerInterceptor. Also interaction could be similar to @Controller with the methods allowing use of @ModelAttribute and @RequestParam.

      Example provided by Chris Beams:

      // @HandlerInterceptors are @Components, thus eligible for component scanning.
      // If no class args are supplied, the interceptor applies globally to all 
      // registered @Controllers.  Naturally, specifying one or more classes narrows 
      // its scope.
      
      @HandlerInterceptor({AccountController.class, CustomerController.class}) public class ExceptionLoggingHandlerInterceptor {
      	@AfterCompletion
      	public void logException(Object handler, Throwable ex) {
      		logger.error(...);
      	}
      
      	// Or to be more explicit, do it @AspectJ-style, using
      	// attributes to bind by name
      
      	@AfterCompletion(handler="handler", exception="ex")
      	public void logException(Object handler, Throwable ex) {
      		logger.error(...);
      	}
      
      	// In keeping with @Controller methods, the user could
      	// request the request, response, model, etc.
      
      	@AfterCompletion(handler="handler", exception="ex")
      	public void logException(HttpServletRequest req, Object handler, Throwable ex) {
      		logger.error(...);
      	}
      
      	// Could even have handler methods return @ModelAttributes!
      
      	@PreHandle
      	public @ModelAttribute("currentDate") Date currentDate(/* no params needed, none requested */) {
      		return new Date();
      	}
      
      }
      

      Obviously there's a lot to be worked out. Some questions we have are:

      • How do you express the order of the interceptors, something that comes naturally in the <list> configuratin. @Order?
      • Is it more natural to express the Controller classes the HandlerInterceptor applies to in the @HandlerInterceptor (above) or would something like @Controller(interceptors=(@HandlerInterceptors {class, class, ...}

        )) be more expressive? which is more flexible?

        • The later does express the list naturally but you would have to repeat the list in multiple controllers to achieve the same behavior.
        • Maybe an XML annotation hybrid? <handlerInterceptorList id="authInterceptors">...</handlerInterceptorList> and @Controller(interceptor="authInterceptors")
      • Could tooling help visualize how an @Controller relates to it @HandlerInterceptors (add bonus for sure!)

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                rstoya05-aop Rossen Stoyanchev
                Reporter:
                dpedowitz David Pedowitz
                Last updater:
                Rossen Stoyanchev
              • Votes:
                14 Vote for this issue
                Watchers:
                16 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  3 years, 47 weeks, 4 days ago