Chinaunix首页 | 论坛 | 博客
  • 博客访问: 256036
  • 博文数量: 45
  • 博客积分: 170
  • 博客等级: 入伍新兵
  • 技术积分: 488
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-13 14:43
文章分类

全部博文(45)

文章存档

2014年(2)

2013年(35)

2012年(8)

我的朋友

分类: Java

2013-07-14 18:54:40

struts2提供了一个命名空间的概念,可以通过package的namespace属性来设置,使用它可以避免action的名字冲突,同时也可以在逻辑上给action分类。关于namesapce的很多信息,可以参考strtus的官方文档,地址是:。

个人觉得,这个里面还是很多信息没有表达清楚。例如该文档最后有一段话如下:

Namespaces are not a path!
Namespace are not hierarchical like a file system path. There is one namespace level. For example if the URL /barspace/myspace/bar.action is requested, the framework will first look for namespace /barspace/myspace. If the action does not exist at /barspace/myspace, the search will immediately fall back to the default namespace "". The framework will not parse the namespace into a series of "folders". In the Namespace Example, the bar action in the default namespace would be selected.

大概意思就是说,如果在某个命令空间下没有找到对应的action,然后就直接去缺省的命名空间下。但事实真的如此吗?

通过一些测试,发现似乎遵循如下的规则:

1.假设请求路径的URI,例如url是:

2.首先寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤3。

3.寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤4。

4. 寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,转步骤5;如果不存在转步骤5。

5. 如果存在缺省的命名空间,就在该package下查找名字为test的action,若找到则执行,否则页面提示找不到action;否则提示面提示找不到action。

上述一个很重要的地方就是一旦找到对应的namespace的package就停止向上级路径查找了,另外缺省命名空间(package中没有指明namespace属性或namespace属性值为空)的package的可以不存在。

以前一直比较困惑的是,当访问成功,那类似也能正常访问,而且执行的同一个action。而上述的试验结果可以很好的解释这个疑惑了。但是个人觉得这样的设计不是太好,决定去源码看个究竟,在org.apache.struts2.dispatcher.mapper.DefaultActionMapper找到关于如何在namespace中查找action的操作,有如下代码:

    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 slash
            namespace = uri.substring(0, lastSlash);
            name = uri.substring(lastSlash + 1);
        } else {

注意到其中alwaysSelectFullNamespace这个信息,原来它属于struts.properties常用配置的一项,其作用是控制是否一直在最后一个slash之前的任何位置选定namespace。由于struts2默认是设置是false,所以导致按照上述试验结果成功,当把alwaysSelectFullNamespace在strtus.properties中设置为true时,此时struts2查找action就不会递归路径去查找package,而是直接找路径对应的package,如果没有找到就去默认命名空间下查找,这就是官方文档中所采用的说法。

个人建议把alwaysSelectFullNamespace设置为true,明确指定action在属于命名空间的package中,不会操作url路径随便输入的问题,同时执行效率也会略有提高。

    来源:

阅读(5068) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~