在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping定义了抽象方法buildUrlsForHandler,接下来我们看看在其子类ControllerClassNameHandlerMapping中的实现。

ControllerClassNameHandlerMapping中buildUrlsForHandler实现如下,根据beanClass来获取url

@Override
	protected String[] buildUrlsForHandler(String beanName, Class<?> beanClass) {
		return generatePathMappings(beanClass);
	}
	protected String[] generatePathMappings(Class<?> beanClass) {
		StringBuilder pathMapping = buildPathPrefix(beanClass);
		String className = ClassUtils.getShortName(beanClass);
		String path = (className.endsWith(CONTROLLER_SUFFIX) ?
				className.substring(0, className.lastIndexOf(CONTROLLER_SUFFIX)) : className);
		if (path.length() > 0) {
			if (this.caseSensitive) {
				pathMapping.append(path.substring(0, 1).toLowerCase()).append(path.substring(1));
			}
			else {
				pathMapping.append(path.toLowerCase());
			}
		}
		if (isMultiActionControllerType(beanClass)) {
			return new String[] {pathMapping.toString(), pathMapping.toString() + "/*"};
		}
		else {
			return new String[] {pathMapping.toString() + "*"};
		}
	}
	private StringBuilder buildPathPrefix(Class<?> beanClass) {
		StringBuilder pathMapping = new StringBuilder();
		if (this.pathPrefix != null) {
			pathMapping.append(this.pathPrefix);
			pathMapping.append("/");
		}
		else {
			pathMapping.append("/");
		}
		if (this.basePackage != null) {
			String packageName = ClassUtils.getPackageName(beanClass);
			if (packageName.startsWith(this.basePackage)) {
				String subPackage = packageName.substring(this.basePackage.length()).replace('.', '/');
				pathMapping.append(this.caseSensitive ? subPackage : subPackage.toLowerCase());
				pathMapping.append("/");
			}
		}
		return pathMapping;
	}

完整的ControllerClassNameHandlerMapping的源码实现如下:

public class ControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping {

	private static final String CONTROLLER_SUFFIX = "Controller";
	private boolean caseSensitive = false;
	private String pathPrefix;
	private String basePackage;
	public void setCaseSensitive(boolean caseSensitive) {
		this.caseSensitive = caseSensitive;
	}
	public void setPathPrefix(String prefixPath) {
		this.pathPrefix = prefixPath;
		if (StringUtils.hasLength(this.pathPrefix)) {
			if (!this.pathPrefix.startsWith("/")) {
				this.pathPrefix = "/" + this.pathPrefix;
			}
			if (this.pathPrefix.endsWith("/")) {
				this.pathPrefix = this.pathPrefix.substring(0, this.pathPrefix.length() - 1);
			}
		}
	}
	public void setBasePackage(String basePackage) {
		this.basePackage = basePackage;
		if (StringUtils.hasLength(this.basePackage) && !this.basePackage.endsWith(".")) {
			this.basePackage = this.basePackage + ".";
		}
	}
	@Override
	protected String[] buildUrlsForHandler(String beanName, Class<?> beanClass) {
		return generatePathMappings(beanClass);
	}
	protected String[] generatePathMappings(Class<?> beanClass) {
		StringBuilder pathMapping = buildPathPrefix(beanClass);
		String className = ClassUtils.getShortName(beanClass);
		String path = (className.endsWith(CONTROLLER_SUFFIX) ?
				className.substring(0, className.lastIndexOf(CONTROLLER_SUFFIX)) : className);
		if (path.length() > 0) {
			if (this.caseSensitive) {
				pathMapping.append(path.substring(0, 1).toLowerCase()).append(path.substring(1));
			}
			else {
				pathMapping.append(path.toLowerCase());
			}
		}
		if (isMultiActionControllerType(beanClass)) {
			return new String[] {pathMapping.toString(), pathMapping.toString() + "/*"};
		}
		else {
			return new String[] {pathMapping.toString() + "*"};
		}
	}
	private StringBuilder buildPathPrefix(Class<?> beanClass) {
		StringBuilder pathMapping = new StringBuilder();
		if (this.pathPrefix != null) {
			pathMapping.append(this.pathPrefix);
			pathMapping.append("/");
		}
		else {
			pathMapping.append("/");
		}
		if (this.basePackage != null) {
			String packageName = ClassUtils.getPackageName(beanClass);
			if (packageName.startsWith(this.basePackage)) {
				String subPackage = packageName.substring(this.basePackage.length()).replace('.', '/');
				pathMapping.append(this.caseSensitive ? subPackage : subPackage.toLowerCase());
				pathMapping.append("/");
			}
		}
		return pathMapping;
	}
}

springMVC源码分析--ControllerClassNameHandlerMapping(九)的更多相关文章

  1. 8、SpringMVC源码分析(3):分析ModelAndView的形成过程

    首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...

  2. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

  3. springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)

    之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...

  4. springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)

    在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...

  5. springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

    之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...

  6. springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod

    在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...

  7. springMVC源码分析--RequestMappingHandlerAdapter(五)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  8. springMVC源码分析--HttpRequestHandlerAdapter(四)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  9. springMVC源码分析--SimpleControllerHandlerAdapter(三)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

随机推荐

  1. java中的链表编写

    通过while循环取出节点内容 class Node{//定义一个节点类,用于保存数据和取得下一个节点 private String data;//节点中数据 private Node next;// ...

  2. 半径无关快速高斯模糊实现(附完整C代码)

    之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...

  3. Evensgn 捡树枝

    问题 A: Evensgn 剪树枝 时间限制: 1 Sec  内存限制: 128 MB 题目描述 繁华中学有一棵苹果树.苹果树有 n 个节点(也就是苹果),n − 1 条边(也就 是树枝).调皮的 E ...

  4. Codeforces 700E. Cool Slogans

    Description 给定一个串 \(S\),求一个序列 \(a_i\),满足 \(a_i\) 是原串的子串,且 \(a_i\) 在 \(a_{i-1}\) 中至少出现两次,求这个序列的最大的长度 ...

  5. ●BZOJ 2434: [Noi2011]阿狸的打字机

    ●赘述题目 (题意就不赘述了) ●解法: ●我先想的一个比较暴力的方法(要TLE): (ac自动机)先求出last数组(参见刘汝佳的解释:last[j]:表示j节点沿着失配指针往回走时,遇到的下一个单 ...

  6. 2015 多校联赛 ——HDU5386(暴力)

    Sample Input 1 3 5 2 2 1 2 3 3 2 1 3 3 3 3 3 3 3 3 3 3 H 2 3 L 2 2 H 3 3 H 1 3 L 2 3   Sample Output ...

  7. hdu 4747 线段树

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  8. SpringBoot学习之mvc

    Spring Boot非常适合Web应用程序开发. 我们可以使用嵌入式Tomcat,Jetty或Undertow轻松创建自包含的HTTP服务器. 大多数Web应用程序将使用spring-boot-st ...

  9. Union和Union All 的区别

    Union和Union All 的区别: Union 是对结果集进行并集操作,不包括重复行,同时进行默认规则的排序: Union All,对两个结果集进行并集操作,包括重复行,不进行排序: Inter ...

  10. C语言程序设计第一次作业1

    (一)实验总结 1. 圆面积问题 1:求圆面积和周长 (1)输入圆的半径,计算圆的周长和面积. (2) (3) 2:判断闰年 (1)输入一个四位年份,判断其是否是闰年.闰年的判别条件是该年年份能被4整 ...