ControllerClassNameHandlerMapping类详解 - HandlerMapping系列六
ControllerClassNameHandlerMapping通过声明在Web应用程序环境中的控制器类型来注册处理器映射的。它从控制器的类型转换出控制器所服务的URL Pattern。这个转换规则是,把点号分割的具有包前缀的类名替换成斜线(/)分割的具有包前缀的字符串,再加上前缀和后缀构成URL Pattern,然后,使用得到的Pattern匹配请求的URL,如果匹配成功,则使用匹配的Bean作为处理器返回。
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 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 + "."; } } //根据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); // 如果以控制器后缀(Controller)结尾,则移除控制器后缀 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()); } } // 如果是多行为控制器类型,则加URL本身和所有的子URL if (isMultiActionControllerType(beanClass)) { return new String[] {pathMapping.toString(), pathMapping.toString() + "/*"}; } // 否则只加URL本身 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 作用是将MyController这样的名字, 自动映射成 /my/** 这样的URL
版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。