【发布时间】:2013-02-16 18:18:46
【问题描述】:
有两个动作,*_*在**前面(默认命名空间在特定命名空间之后才起作用完全没有关系(除非特定命名空间扩展它))
<package name="default" namespace="" extends="struts-default"></package>
<package name="admin" namespace="/admin" extends="default">
<global-results>
<result>/admin/result.jsp</result>
</global-results>
<action name="login" class="org.cc.action.AdminAction">
<result>/admin/admin.jsp</result>
</action>
<action name="*_*" class=org.cc.action.{1}Action" method="{2}">
</action>
</package>
<package name="error" namespace="" extends="default">
<action name="**" >
<result>/error.jsp</result>
</action>
</package>
我为捕捉不存在的动作定义了一个错误页面
然后我测试了类似的动作
localhost:8080/myProjectName/admin/AdminAction.action
(不存在)
但它被名为"*_*" 的操作捕获,因为异常显示未找到AdminActionAction.class。
然后我使用了*__*(有两个'_')。它运行良好并显示了error.jsp。
"*a*" 或 "*#*" 之类的格式也不起作用,即使动作名称中没有 a 和 #,它们也会捕获任何动作。
我使用 Struts 2.3.4。
* 和* 之间是否有任何文件说必须至少有两个字符,否则就像*?
这里是异常的详细信息
Unable to instantiate Action, org.cc.action.AdminActionAction, defined for 'AdminAction' in namespace '/admin'org.cc.action.AdminActionAction
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:319)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:400)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:501)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
java.lang.ClassNotFoundException: org.cc.action.AdminActionAction
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
com.opensymphony.xwork2.util.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:152)
com.opensymphony.xwork2.ObjectFactory.getClassInstance(ObjectFactory.java:108)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:161)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:300)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:400)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:501)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
这很容易看出
localhost:8080/myProjectName/admin/AdminAction.action
(不存在)被抓到了
<action name="*_*" class="net.org.cc.{1}Action" method="{2}">
【问题讨论】:
-
请显示完整的堆栈跟踪/错误消息以及完整的 struts.xml(如果定义了很多操作,最好是产生此错误的最小 struts.xml)。还要提及是否安装了 struts2-conventions 插件或任何其他插件。这听起来很像
com.opensymphony.xwork2.util.WildcardHelper(默认模式匹配器)的问题,这个包已经过很好的测试,但是我创建了一个新的测试来确保自己没有问题,符合您特定要求的测试通过了。问题不在于它可以按预期处理这些模式。 -
在您的情况下,哪个模式在另一个“前面”并不重要,因为它们位于单独的包中。我认为应该首先搜索包“”,因为总是首先搜索更具体的包,然后它会回退到“”。包 "" 因此是一种包罗万象的东西,所以首先拥有它会让您想起它的非典型行为。当然,这并不能解决您的问题,只是消除一个不相关的误解。
-
现在我使用
Admin_*而不是*_*来匹配Admin_add.actionAdmin_del.action等动作。当我点击localhost:8080/myProjectName/admin/AdminAction.action(it doesn't exist)时,它可以很好地显示error.jsp .但我的问题是为什么*_*可以匹配`AdminAction.action(不存在)'。 -
这似乎是一个错误。我也有同样的行为……很奇怪。
-
问题也会影响 2.3.8。
标签: java struts2 struts url-mapping wildcard-mapping