The HandlerInterceptor
interface has a parameter Object handler
, which means implementing code has to do type checking on the handler object in order to use it, and cast it as appropriate.
Code snippets I've found seem to assume the handler is always a HandlerMethod
object and return true if this isn't the case, but I want to understand why this seems to be a common implementation to make a robust implementation.
A standard way of implementing this interface seems to be:
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
// ...
return x; // whether or not to proceed with execution
}
return true; // fallback value in case handler wasn't a HandlerMethod
}
}
The Spring javadoc seems to ignore the fact that the interface has an Object type in it, it's very unhelpful for my understanding of this interface.
Some questions that might aid my understanding of how this interface is supposed to be implemented:
- Why is
true
a sensible default if we get a handler that's not the object we expect it to be? - Which types can an
HandlerInterceptor
take for itshandler
parameter? - Under what circumstances could
handler
be a different type, if any? - Why is it an
Object
, not aHandlerMethod
, parameter?
CodePudding user response:
Basically the handler
argument can be any type for which a HandlerAdapter
exists. Most commonly used will be the RequestMappingHandlerAdapter
utilizing a HandlerMethod
.
But it could be a regular class, a servlet, or even a function (when using the functional approach). Spring Web Services also has an implementation as well as Spring Integration.
Spring itself will support the following out-of-the-box
HandlerMethod
HandlerFunction
Controller
Servlet
HttpRequestHandler
WsdlDefinition
(Spring Web Services)XsdDefinition
(Spring Web Services)
So no it isn't always a HandlerMethod
but it will be for most users.
CodePudding user response:
Here's what javadoc of HandlerInterceptor#preHandle()
says:
Interception point before the execution of a handler. Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler.
DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can decide to abort the execution chain, typically sending an HTTP error or writing a custom response.
This means interceptors are not supposed to touch the handler
at all so they don't need to know anything about it. Their only job is to decide whether to pass the request further or not.
BTW, none of the standard HandlerInterceptor#preHandle()
implementations in org.springframework.web.servlet.*
try to analyze the true handler
parameter type and do any logic based on it.
Why is it an Object, not a HandlerMethod, parameter?
From the org.springframework.web.servlet.HandlerMapping#getHandler()
javadoc:
Return a handler and any interceptors for this request. The choice may be made on request URL, session state, or any factor the implementing class chooses.
The returned HandlerExecutionChain contains a handler Object, rather than even a tag interface, so that handlers are not constrained in any way. For example, a HandlerAdapter could be written to allow another framework's handler objects to be used.