Skip to content

@HandlerInterceptor [SPR-4770] #9447

Closed
Closed
@spring-projects-issues

Description

@spring-projects-issues

David Pedowitz opened SPR-4770 and commented

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!)

Issue Links:

14 votes, 16 watchers

Metadata

Metadata

Assignees

Labels

has: votes-jiraIssues migrated from JIRA with more than 10 votes at the time of importin: webIssues in web modules (web, webmvc, webflux, websocket)status: declinedA suggestion or change that we don't feel we should currently applytype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions