(1)MappingRuleService
负责映射关系转换,包括将url转化为target或target转化为url,target映射为模块等
(2)ExtensionMappingRule
1.作用
将url转化为target,或将target转换为url2.原理
使用web-component-and-root定义的转换规则,对url进行转换输入规则定义:
<mapping-rules:extension-rule id="extension.input">
<!-- 默认后缀 -->
<mapping extension="" to="" />
<!-- JSP -->
<mapping extension="jhtml" to="" />
<mapping extension="jsp" to="" />
<mapping extension="jspx" to="" />
<mapping extension="php" to="" />
<!-- Velocity -->
<mapping extension="htm" to="" />
<mapping extension="vhtml" to="" />
<mapping extension="vm" to="" />
</mapping-rules:extension-rule>
输出规则定义:
<mapping-rules:extension-rule id="extension.output">
<!-- 默认后缀 -->
<mapping extension="" to="htm" />
<!-- JSP -->
<mapping extension="jhtml" to="jhtml" />
<mapping extension="jsp" to="jhtml" />
<mapping extension="jspx" to="jhtml" />
<mapping extension="php" to="jhtml" />
<!-- Velocity -->
<mapping extension="htm" to="htm" />
<mapping extension="vhtml" to="htm" />
<mapping extension="vm" to="htm" />
</mapping-rules:extension-rule>
其中id表示不同的类型,比如extension.input表示输入,extension.output表示输出
子标签中的extension表示源后缀,to表示目标后缀
public String doMapping(String name) {
FileNameAndExtension names = getFileNameAndExtension(name, true);
String extension = names.getExtension(); // 可能为null
if (extension == null) {
extension = EMPTY_STRING;
} else {
extension = extension.toLowerCase();
}
// 如果映射规则存在,则替换后缀
if (extensionMappings.containsKey(extension)) {
String mapToExtension = extensionMappings.get(extension);
name = names.getFileName(); // 总不为null
// 如果以/结尾,就不加后缀。
if (name.length() == 0 || !StringUtil.contains(NAME_SEPARATOR, name.charAt(name.length() - 1))) {
// 如果获取的映射后缀不为空,则加上后缀
if (!StringUtil.isEmpty(mapToExtension)) {
name = name + EXTENSION_SEPARATOR + mapToExtension;
}
}
} else {
// 当后缀不在映射规则中,且后缀为空,则至返回除了后缀前面的部分
if (StringUtil.isEmpty(extension)) {
name = names.getFileName();
}
}
return name;
}
(3)DirectModuleMappingRule
1.作用
将target映射到module 比如http://localhost:8081/simple/say_hi.do,对应的target是simple/sayHi,对应到代码中就是simple->SayHi.java
2.原理
将url中的‘/’替换成‘.’,并去除后缀名即可 配置信息 <mapping-rules:direct-module-rule id="screen.notemplate" />
源码:
public String doMapping(String name) {
String[] parts = StringUtil.split(name, NAME_SEPARATOR); //使用/来分割
if (ArrayUtil.isEmptyArray(parts)) {
return throwInvalidNameException(name);
}
parts[parts.length - 1] = normalizeClassName(parts[parts.length - 1]); //肯定最后一个才有后缀,去掉
if (parts[parts.length - 1] == null) {
return throwInvalidNameException(name);
}
return StringUtil.join(parts, MODULE_NAME_SEPARATOR); //用.来拼接
}
(4)FallbackModuleMappingRule
1.作用
与DirectModuleMappingRule相同,将target转化为module,只是如果找不到就会层层向上找,如果最终没找到,就返回模块中第一个class2.原理
配置如下:<mapping-rules:direct-template-rule id="screen.template" templatePrefix="screen" />
调用module loader service检查模块是否存在,如果不存在,就查找上一级模块,一直找直至根目录
如果一直找不到,则返回第一个类名
源码如下: public String doMapping(String name) {
FallbackIterator iter = new FallbackModuleIterator(name, defaultName, matchLastName);
String moduleName = null;
String firstModuleName = iter.getNext(); // 保存第一个精确的类,万一找不到,就返回这个值
while (iter.hasNext()) {
moduleName = iter.next();
log.debug("Looking for module: " + moduleName);
try {
if (getModuleLoaderService().getModuleQuiet(getModuleType(), moduleName) != null) {
return moduleName;
} // else 继续查找
} catch (ModuleLoaderException e) {
throw new MappingRuleException(e);
}
}
return firstModuleName;
}
(5)TemplateMappingRule
1.作用
将target映射到template webx中我们采用模板引擎来渲染html输出。为了定位模板名,我们需要定义target到template路径的映射,这就是TemplateMapping的作用
2.原理
与module查询完全相同,也是分为直接查找和fallback查找 <mapping-rules:direct-template-rule id="screen.template" templatePrefix="screen" />
<mapping-rules:fallback-template-rule id="layout.template" templatePrefix="layout" />
(6)注意
1.对于target映射module,使用哪种映射方式是根据valve来确定的
<when>
<!-- 执行带模板的screen,默认有layout。 -->
<pl-conditions:target-extension-condition extension="null" />
<pl-valves:performAction />
<pl-valves:performTemplateScreen />
<pl-valves:renderTemplate />
</when>
<when>
<!-- 执行不带模板的screen,无layout。 -->
<pl-conditions:target-extension-condition extension="do" />
<pl-valves:performAction />
<pl-valves:performScreen />
</when>
第一种的valve是PerformTemplateScreenValve,而获得模块名称传递的参数如下:
protected String getModuleName(String target) {
return getMappingRuleService().getMappedName(SCREEN_MODULE, target);
}
传递的是screen,正好与webx-component-and-root.xml中定义的
<mapping-rules:fallback-module-rule id="screen" moduleType="screen" />
一致,因而使用的是FallbackModuleMappingRule
而第二种的valve是PerformScreenValve,而获得模块名称传递的参数如下:
protected String getModuleName(String target) {
return mappingRuleService.getMappedName(SCREEN_MODULE_NO_TEMPLATE, target);
}
传递的是screen.notemplate,
正好与webx-component-and-root.xml中定义的
<mapping-rules:direct-module-rule id="screen.notemplate" />
一致,因而使用的是DirectModuleMappingRule
2.cache
设置每种映射是否启用缓存,启用之后可以减少模板查找的开销,提高映射效率
开启方法:
<direct-module-rule id="direct.module" cacheEnabled="${cacheEnabled:false}" />