从源码总结struts2命名空间的匹配规则

以前看帖子中经常发现有关于命名空间的问题,如:有关””与”/”的区别、模糊匹配的规律等,下面是我根据源码中分析、总结的规律,希望对大家有所帮助。如果存在异议,希望大家能够及时反映。

采用的版本是struts2-2.1.6。

struts2中的命名空间归结起来其实有三种:

第一种:空,即””。这是默认的配置,香港虚拟主机,如果用户在配置文件中没有显示说明命名空间,将采用空(“”)。

第二中:”/”,即根空间。可以在配置文件中直接配置。

第三种:”/任意字符”,当然这里的任意字符当然是符合命名规则的。如:”/common”,”/common/user”等。

下面通过分析源码来看下如何从请求的url中分析出命名空间,以及如何利用此命名空间去和我们配置的命名空间进行匹配,通过一些匹配规则来检索出最终的命名空间。如下:

/*** Parses the name and namespace from the uri** @param uri*The uri* @param mapping*The action mapping to populate*/protected void parseNameAndNamespace(String uri, ActionMapping mapping,ConfigurationManager configManager) {String namespace, name;int lastSlash = uri.lastIndexOf(“/”);if (lastSlash == -1) {namespace = “”;name = uri;} else if (lastSlash == 0) {// ww-1046, assume it is the root namespace, it will fallback to// default// namespace anyway if not found in root namespace.namespace = “/”;name = uri.substring(lastSlash + 1);} else if (alwaysSelectFullNamespace) {// Simply select the namespace as everything before the last slashnamespace = uri.substring(0, lastSlash);name = uri.substring(lastSlash + 1);} else {// Try to find the namespace in those defined, defaulting to “”Configuration config = configManager.getConfiguration();String prefix = uri.substring(0, lastSlash);namespace = “”;boolean rootAvailable = false;// Find the longest matching namespace, defaulting to the defaultfor (Object cfg : config.getPackageConfigs().values()) {String ns = ((PackageConfig) cfg).getNamespace();if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == ‘/’)) {if (ns.length() > namespace.length()) {namespace = ns;}}if (“/”.equals(ns)) {rootAvailable = true;}}name = uri.substring(namespace.length() + 1);// Still none found, use root namespace if foundif (rootAvailable && “”.equals(namespace)) {namespace = “/”;}}if (!allowSlashesInActionNames && name != null) {int pos = name.lastIndexOf(‘/’);if (pos > -1 && pos < name.length() – 1) {name = name.substring(pos + 1);}}mapping.setNamespace(namespace);mapping.setName(name);}

String namespace, name;int lastSlash = uri.lastIndexOf(“/”);

首先定义存放命名空间、action名称的局部变量namespace, name。然后通过uri.lastIndexOf(“/”)句从后往前搜索第一个”/”的位置,将下标存于lastSlash (译为最后的斜杠)中。

if (lastSlash == -1) {namespace = “”;name = uri;}

if (lastSlash == -1)即当uri中不存在”/”时,将命名空间namespace设为””,将name设为uri。例如当前的uri形式为index!index, 此时namespace为””,name为“index!index”。但这种情况在实际使用中几乎看不到,我也想不出在什么情况下会出现,有知道的朋友可以贴出来和大家分享下。

} else if (lastSlash == 0) {// ww-1046, assume it is the root namespace, it will fallback to// default// namespace anyway if not found in root namespace.namespace = “/”;name = uri.substring(lastSlash + 1);}

if (lastSlash == 0)即当uri以”/”开头时,并且uri中只存在一个”/”时,命名空间namespace设为”/”,name设为去掉”/”后的uri。这种情况就是在http请求的URL地址中省略了命名空间,如

else if (alwaysSelectFullNamespace) {// Simply select the namespace as everything before the last slashnamespace = uri.substring(0, lastSlash);name = uri.substring(lastSlash + 1); }

} else {// Try to find the namespace in those defined, defaulting to “”Configuration config = configManager.getConfiguration();String prefix = uri.substring(0, lastSlash);namespace = “”;boolean rootAvailable = false;// Find the longest matching namespace, defaulting to the defaultfor (Object cfg : config.getPackageConfigs().values()) {String ns = ((PackageConfig) cfg).getNamespace();if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == ‘/’)) {if (ns.length() > namespace.length()) {namespace = ns;}}if (“/”.equals(ns)) {rootAvailable = true;}}name = uri.substring(namespace.length() + 1);// Still none found, use root namespace if foundif (rootAvailable && “”.equals(namespace)) {namespace = “/”;}}

当上面的所有条件都不满足时,其中包括

if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == ‘/’)) {if (ns.length() > namespace.length()) {namespace = ns;}}

好,网站空间,这部分代码说完了,返回前一个代码,接着看:

无论身处何处,只要有一颗放松而美好的心态,生活便是美好!

从源码总结struts2命名空间的匹配规则

相关文章:

你感兴趣的文章:

标签云: