深入理解struts2的namespace

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

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

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是:http://www.netingcn.com/path1/path2/test.do

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的可以不存在。

以前一直比较困惑的是,当访问http://www.netingcn.com/test.do成功,那类似http://www.netingcn.com/x/test.do,http://www.netingcn.com/x/y/test.do也能正常访问,而且执行的同一个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路径随便输入的问题,同时执行效率也会略有提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值