查阅百度和书上都是这样解释命名空间的:
如果请求的url是/bookservice/search/get,系统将先在/bookservice/search的命名空间下查找名为get的action,如果在该命名空间内找到名为get的action,则由该action处理用户请求;如果在该命名空间内没有找到名为get的action,系统将直接进入默认的命名空间中查找名为get的action,而不会在/bookservice的命名空间或者根命名空间/下查找。
然而,我经过许多次测试,结果都没有和这段话吻合。终于在Struts2关于命名空间的详细讨论的博客中找到了答案:
当我们访问一个action的url为/a/b/c/d/echo时,系统是分两个步骤去找action的:
- 找包。一层一层往上找,先找是否存在命名空间为/a/b/c/d的包,若没有,则再往上一层找是否存在命名空间为/a/b/c的的包,若没有,依次查找命名空间为/a/b的包、命名空间为/a的包、根命名空间的包、默认命名空间的包。找到包即返回,若找不到,就报错。
- 第二步才是按照开头引用的那段话那样,在第一步找到的该包下查找名为echo的action,如果没有找到,就直接去默认命名空间的包中查找名为get的action。
示例:struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--默认命名空间-->
<package name="test1" extends="struts-default">
<action name="echo" class="struts2.EchoAction">
<result name="success">/test1.jsp</result>
</action>
</package>
<!--根命名空间-->
<package name="test2" namespace="/" extends="struts-default">
<action name="echo" class="struts2.EchoAction">
<result name="success">/test2.jsp</result>
</action>
</package>
<!--/a命名空间-->
<package name="test3" namespace="/a" extends="struts-default">
<action name="echo" class="struts2.EchoAction">
<result name="success">/test3.jsp</result>
</action>
</package>
<!--/a/b命名空间-->
<package name="test4" namespace="/a/b" extends="struts-default">
<action name="hello" class="struts2.EchoAction">
<result name="success">/test4.jsp</result>
</action>
</package>
</struts>
各种请求的url结果页面:
- /a/b/d/hello:test4.jsp(先找到/a/b包,再找到它之下的hello)
- /a/b/d/echo:test1.jsp(先找到/a/b包,找不到echo,直接找默认包,再找到它之下的echo)
- /c/a/b/d/echo:test2.jsp(先找到根/包,再找到它之下的echo)