HandlerMapping 和Handler也是 SpringMVC中重要的一环。它们负责为我们的URL请求找到我们指定的方法来进行处理。
一. HandlerMapping
1.1. HandlerMapping 的一些基础点
对于一个HandlerMapping接口,它的最主要职责就是定义了请求的URL映射和我们定义的方法之间的关系。通俗点说就是定义了哪个请求响应哪个类的方法
。源码证明:
* Interface to be implemented by objects that define a mapping between
* requests and handler objects.
在该接口中,有一个重要的方法就是
:
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
该方法的目的是我们可以理解成返回一个拦截器链。这个拦截器链包含了该请求的所有拦截器以及我们处理请求的Handler。全部的拦截器链的preHandler()方法返回true的时候,我们处理请求的Handler就会被执行。
我们一直在说的Handler是个什么东西? 你暂且可以理解为就是我们的处理方法,为什么可以这样说,因为看HandlerMapping的实现类中,下面两段代码说的比较清楚了。
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
... ...
return getHandlerExecutionChain(handler, request);
}
/**
* Look up a handler method for the given request.
*/
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler method for path " + lookupPath);
}
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
... ...
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
以上就是HandlerMapping 的一些基础知识,暂且我们可以记住两点:
- HandlerMapping 定义了 URL映射和我们处理的方法之间的关系。
- Handler 可以理解为我们 具体的请求方法。
还有一些 比如说HandlerMapping是如何匹配URL 和指定方法之间的关系。这里就不再做深入的研究。
1.2 HandlerMapping 在DispatcherServlet的使用
在DispatcherServlet的核心方法doDispatch()方法中,没有出现HandlerMapping,但是有下面一句(完整方法可以自行查看其方法):
mappedHandler = getHandler(processedRequest);
在该代码里面:
/**
* Return the HandlerExecutionChain for this request.
* <p>Tries all handler mappings in order.
* @param request current HTTP request
* @return the HandlerExecutionChain, or {@code null} if no handler could be found
*/
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
可以看到,首先,DispatcherServlet会利用HandlerMapping来得到一个HandlerExecution对象,也可以理解成一个拦截器链。这样,才能有后续的执行我们具体的方法动作。
总结:
1.
HandlerMapping 定义了 URL映射和我们处理的方法之间的关系。
2.
HandlerMapping
有一个重要方法 getHandler(),可以为我们返回一个拦截器链。
Ps:有些知识没展开,比如说拦截器链,读者可以自行查找相关资料;比如说具体是如何进行匹配,这些留到以后在研究。