springMVC源码分析--AbstractUrlHandlerMapping(三)
来源:互联网 发布:战地4优化 编辑:程序博客网 时间:2024/05/13 03:54
上一篇博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMapping了,接下来我们介绍其子类AbstractUrlHandlerMapping。
在上一篇博客中我们了解到AbstractHandlerMapping提供了一个抽象类getHandlerInternal(HttpServletRequest request),我们首先看看AbstractUrlHandlerMapping中对抽象类getHandlerInternal(HttpServletRequest request)的实现。
[java] view plain copy print?
- //获取Handler,主要是通过url和method的对应关系来查找
- @Override
- protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
- //获取request中的请求链接
- String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
- //根据链接查找handler
- Object handler = lookupHandler(lookupPath, request);
- if (handler == null) {
- // We need to care for the default handler directly, since we need to
- // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
- //定义一个变量,保存找到的原始Handler
- Object rawHandler = null;
- if ("/".equals(lookupPath)) {
- rawHandler = getRootHandler();
- }
- if (rawHandler == null) {
- rawHandler = getDefaultHandler();
- }
- if (rawHandler != null) {
- // Bean name or resolved handler?
- //如果是String类型则到容器中查找具体的Bean
- if (rawHandler instanceof String) {
- String handlerName = (String) rawHandler;
- rawHandler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(rawHandler, request);
- handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
- }
- }
- if (handler != null && logger.isDebugEnabled()) {
- logger.debug("Mapping [" + lookupPath + "] to " + handler);
- }
- else if (handler == null && logger.isTraceEnabled()) {
- logger.trace("No handler mapping found for [" + lookupPath + "]");
- }
- return handler;
- }
[java] view plain copy print?
- protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
- // Direct match?
- //直接从map中获取
- Object handler = this.handlerMap.get(urlPath);
- if (handler != null) {
- // Bean name or resolved handler?
- //如果是String类型则从容器中获取
- if (handler instanceof String) {
- String handlerName = (String) handler;
- handler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(handler, request);
- return buildPathExposingHandler(handler, urlPath, urlPath, null);
- }
- // Pattern match?
- //通过模糊匹配来查找
- List<String> matchingPatterns = new ArrayList<String>();
- for (String registeredPattern : this.handlerMap.keySet()) {
- if (getPathMatcher().match(registeredPattern, urlPath)) {
- matchingPatterns.add(registeredPattern);
- }
- else if (useTrailingSlashMatch()) {
- if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) {
- matchingPatterns.add(registeredPattern +"/");
- }
- }
- }
- String bestPatternMatch = null;
- //匹配规则
- Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
- if (!matchingPatterns.isEmpty()) {
- Collections.sort(matchingPatterns, patternComparator);
- if (logger.isDebugEnabled()) {
- logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
- }
- bestPatternMatch = matchingPatterns.get(0);
- }
- if (bestPatternMatch != null) {
- handler = this.handlerMap.get(bestPatternMatch);
- if (handler == null) {
- Assert.isTrue(bestPatternMatch.endsWith("/"));
- handler = this.handlerMap.get(bestPatternMatch.substring(0, bestPatternMatch.length() - 1));
- }
- // Bean name or resolved handler?
- if (handler instanceof String) {
- String handlerName = (String) handler;
- handler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(handler, request);
- String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);
- // There might be multiple 'best patterns', let's make sure we have the correct URI template variables
- // for all of them
- Map<String, String> uriTemplateVariables = new LinkedHashMap<String, String>();
- for (String matchingPattern : matchingPatterns) {
- if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
- Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
- Map<String, String> decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
- uriTemplateVariables.putAll(decodedVars);
- }
- }
- if (logger.isDebugEnabled()) {
- logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
- }
- return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
- }
- // No handler found...
- return null;
- }
上面两个方法介绍了通过url来查找handlerMap获取handler的操作,AbstractUrlHandlerMapping中也提供了注册url和handler到handlerMap中的操作,具体的调用则要到AbstractUrlHandlerMapping的子类中实现。
[java] view plain copy print?
- //注册url和Bean的map,注册多个string的url到一个处理器中
- protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
- Assert.notNull(urlPaths, "URL path array must not be null");
- for (String urlPath : urlPaths) {
- registerHandler(urlPath, beanName);
- }
- }
- ////注册url和Bean的map,将具体的Handler注入到url对应的map中
- protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
- Assert.notNull(urlPath, "URL path must not be null");
- Assert.notNull(handler, "Handler object must not be null");
- Object resolvedHandler = handler;
- // Eagerly resolve handler if referencing singleton via name.
- //如果Handler是String类型而且没有设置lazyInitHandlers则从springMVC容器中获取handler
- if (!this.lazyInitHandlers && handler instanceof String) {
- String handlerName = (String) handler;
- if (getApplicationContext().isSingleton(handlerName)) {
- resolvedHandler = getApplicationContext().getBean(handlerName);
- }
- }
- Object mappedHandler = this.handlerMap.get(urlPath);
- if (mappedHandler != null) {
- if (mappedHandler != resolvedHandler) {
- throw new IllegalStateException(
- "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
- "]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
- }
- }
- else {
- if (urlPath.equals("/")) {
- if (logger.isInfoEnabled()) {
- logger.info("Root mapping to " + getHandlerDescription(handler));
- }
- setRootHandler(resolvedHandler);
- }
- else if (urlPath.equals("/*")) {
- if (logger.isInfoEnabled()) {
- logger.info("Default mapping to " + getHandlerDescription(handler));
- }
- setDefaultHandler(resolvedHandler);
- }
- else {
- this.handlerMap.put(urlPath, resolvedHandler);
- if (logger.isInfoEnabled()) {
- logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
- }
- }
- }
- }
AbstractUrlHandlerMapping的完整源码如下:
[java] view plain copy print?
- public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
- private Object rootHandler;
- private boolean useTrailingSlashMatch = false;
- private boolean lazyInitHandlers = false;
- private final Map<String, Object> handlerMap = new LinkedHashMap<String, Object>();
- public void setRootHandler(Object rootHandler) {
- this.rootHandler = rootHandler;
- }
- public Object getRootHandler() {
- return this.rootHandler;
- }
- public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) {
- this.useTrailingSlashMatch = useTrailingSlashMatch;
- }
- public boolean useTrailingSlashMatch() {
- return this.useTrailingSlashMatch;
- }
- public void setLazyInitHandlers(boolean lazyInitHandlers) {
- this.lazyInitHandlers = lazyInitHandlers;
- }
- //获取Handler,主要是通过url和method的对应关系来查找
- @Override
- protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
- //获取request中的请求链接
- String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
- //根据链接查找handler
- Object handler = lookupHandler(lookupPath, request);
- if (handler == null) {
- // We need to care for the default handler directly, since we need to
- // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
- //定义一个变量,保存找到的原始Handler
- Object rawHandler = null;
- if ("/".equals(lookupPath)) {
- rawHandler = getRootHandler();
- }
- if (rawHandler == null) {
- rawHandler = getDefaultHandler();
- }
- if (rawHandler != null) {
- // Bean name or resolved handler?
- //如果是String类型则到容器中查找具体的Bean
- if (rawHandler instanceof String) {
- String handlerName = (String) rawHandler;
- rawHandler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(rawHandler, request);
- handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
- }
- }
- if (handler != null && logger.isDebugEnabled()) {
- logger.debug("Mapping [" + lookupPath + "] to " + handler);
- }
- else if (handler == null && logger.isTraceEnabled()) {
- logger.trace("No handler mapping found for [" + lookupPath + "]");
- }
- return handler;
- }
- protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
- // Direct match?
- //直接从map中获取
- Object handler = this.handlerMap.get(urlPath);
- if (handler != null) {
- // Bean name or resolved handler?
- //如果是String类型则从容器中获取
- if (handler instanceof String) {
- String handlerName = (String) handler;
- handler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(handler, request);
- return buildPathExposingHandler(handler, urlPath, urlPath, null);
- }
- // Pattern match?
- //通过模糊匹配来查找
- List<String> matchingPatterns = new ArrayList<String>();
- for (String registeredPattern : this.handlerMap.keySet()) {
- if (getPathMatcher().match(registeredPattern, urlPath)) {
- matchingPatterns.add(registeredPattern);
- }
- else if (useTrailingSlashMatch()) {
- if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) {
- matchingPatterns.add(registeredPattern +"/");
- }
- }
- }
- String bestPatternMatch = null;
- //匹配规则
- Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
- if (!matchingPatterns.isEmpty()) {
- Collections.sort(matchingPatterns, patternComparator);
- if (logger.isDebugEnabled()) {
- logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
- }
- bestPatternMatch = matchingPatterns.get(0);
- }
- if (bestPatternMatch != null) {
- handler = this.handlerMap.get(bestPatternMatch);
- if (handler == null) {
- Assert.isTrue(bestPatternMatch.endsWith("/"));
- handler = this.handlerMap.get(bestPatternMatch.substring(0, bestPatternMatch.length() - 1));
- }
- // Bean name or resolved handler?
- if (handler instanceof String) {
- String handlerName = (String) handler;
- handler = getApplicationContext().getBean(handlerName);
- }
- validateHandler(handler, request);
- String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);
- // There might be multiple 'best patterns', let's make sure we have the correct URI template variables
- // for all of them
- Map<String, String> uriTemplateVariables = new LinkedHashMap<String, String>();
- for (String matchingPattern : matchingPatterns) {
- if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
- Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
- Map<String, String> decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
- uriTemplateVariables.putAll(decodedVars);
- }
- }
- if (logger.isDebugEnabled()) {
- logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
- }
- return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
- }
- // No handler found...
- return null;
- }
- protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {
- }
- //用于给找到的Handler注册两个拦截器PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor
- //这两个拦截器的的作用是将与当前url实际匹配的Pattern、匹配条件和url模板参数设置到request的属性中
- protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
- String pathWithinMapping, Map<String, String> uriTemplateVariables) {
- HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
- chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
- if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
- chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
- }
- return chain;
- }
- protected void exposePathWithinMapping(String bestMatchingPattern, String pathWithinMapping, HttpServletRequest request) {
- request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, bestMatchingPattern);
- request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);
- }
- protected void exposeUriTemplateVariables(Map<String, String> uriTemplateVariables, HttpServletRequest request) {
- request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
- }
- //注册url和Bean的map,注册多个string的url到一个处理器中
- protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
- Assert.notNull(urlPaths, "URL path array must not be null");
- for (String urlPath : urlPaths) {
- registerHandler(urlPath, beanName);
- }
- }
- ////注册url和Bean的map,将具体的Handler注入到url对应的map中
- protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
- Assert.notNull(urlPath, "URL path must not be null");
- Assert.notNull(handler, "Handler object must not be null");
- Object resolvedHandler = handler;
- // Eagerly resolve handler if referencing singleton via name.
- //如果Handler是String类型而且没有设置lazyInitHandlers则从springMVC容器中获取handler
- if (!this.lazyInitHandlers && handler instanceof String) {
- String handlerName = (String) handler;
- if (getApplicationContext().isSingleton(handlerName)) {
- resolvedHandler = getApplicationContext().getBean(handlerName);
- }
- }
- Object mappedHandler = this.handlerMap.get(urlPath);
- if (mappedHandler != null) {
- if (mappedHandler != resolvedHandler) {
- throw new IllegalStateException(
- "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
- "]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
- }
- }
- else {
- if (urlPath.equals("/")) {
- if (logger.isInfoEnabled()) {
- logger.info("Root mapping to " + getHandlerDescription(handler));
- }
- setRootHandler(resolvedHandler);
- }
- else if (urlPath.equals("/*")) {
- if (logger.isInfoEnabled()) {
- logger.info("Default mapping to " + getHandlerDescription(handler));
- }
- setDefaultHandler(resolvedHandler);
- }
- else {
- this.handlerMap.put(urlPath, resolvedHandler);
- if (logger.isInfoEnabled()) {
- logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
- }
- }
- }
- }
- private String getHandlerDescription(Object handler) {
- return "handler " + (handler instanceof String ? "'" + handler + "'" : "of type [" + handler.getClass() + "]");
- }
- public final Map<String, Object> getHandlerMap() {
- return Collections.unmodifiableMap(this.handlerMap);
- }
- protected boolean supportsTypeLevelMappings() {
- return false;
- }
- private class PathExposingHandlerInterceptor extends HandlerInterceptorAdapter {
- private final String bestMatchingPattern;
- private final String pathWithinMapping;
- public PathExposingHandlerInterceptor(String bestMatchingPattern, String pathWithinMapping) {
- this.bestMatchingPattern = bestMatchingPattern;
- this.pathWithinMapping = pathWithinMapping;
- }
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
- exposePathWithinMapping(this.bestMatchingPattern, this.pathWithinMapping, request);
- request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, supportsTypeLevelMappings());
- return true;
- }
- }
- private class UriTemplateVariablesHandlerInterceptor extends HandlerInterceptorAdapter {
- private final Map<String, String> uriTemplateVariables;
- public UriTemplateVariablesHandlerInterceptor(Map<String, String> uriTemplateVariables) {
- this.uriTemplateVariables = uriTemplateVariables;
- }
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
- exposeUriTemplateVariables(this.uriTemplateVariables, request);
- return true;
- }
- }
- }
0 0
- springMVC源码分析--AbstractUrlHandlerMapping(三)
- springMVC源码分析--AbstractUrlHandlerMapping(三)
- springMVC源码分析--SimpleControllerHandlerAdapter(三)
- SpringMVC源码分析--容器初始化(三)HttpServletBean
- springMVC源码分析--拦截器HandlerExecutionChain(三)
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
- springMVC源码分析--HttpMessageConverter写write操作(三)
- springMVC源码分析--页面跳转RedirectView(三)
- SpringMVC源码分析--容器初始化(三)HttpServletBean
- springMVC源码分析--拦截器HandlerExecutionChain(三)
- SpringMVC源码分析(一)
- SpringMVC源码分析(一)
- SpringMVC源码分析(二)
- SpringMVC源码分析(三)之Controller方法参数的工作原理
- springMVC原理(三):详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
- SpringMVC源码(三)Controller控制器
- SpringMVC源码总结(三)mvc:annotation
- 查询本机端口号
- python day12(20170307 )
- java中内部类的学习再学习
- 77. Combinations
- CTF-实验吧-安全杂项-超级纪念品
- springMVC源码分析--AbstractUrlHandlerMapping(三)
- 创建一个数列list-Python
- n-queens puzzle
- 定义图文并茂的html5新标签-figure、figcaption
- mybatis系列笔记(4)---输入输出映射
- NSClassFromString 创建视图控制器
- centos7 安装docker
- js判断字符串真实长度并切分
- Ubuntu下安装arm-linux-gcc-4.4.3.tar.gz (交叉编译环境)