【问题标题】:Why action mapping "*_*" works just like "*"?为什么动作映射“*_*”和“*”一样工作?
【发布时间】: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.action Admin_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


【解决方案1】:

注册了一个错误https://issues.apache.org/jira/browse/WW-3985,但是快速解决方法是使用**_**,这将提供所需的功能

【讨论】:

    【解决方案2】:

    在上面的配置中,映射是使用操作名称AdminAction 和命名空间/admin 创建的。这就是为什么你得到一个例外,因为动作配置匹配器找到了模式"*_*" 的动作配置。但是对于相同动作名称的模式"*__*",它找不到它。因此回退到默认命名空间 "" 并且在此命名空间中它匹配 "**" 模式作为错误页面的结果。

    实际上为这个动作名称创建了两个相似的匹配器,其中一个匹配。创建什么匹配器以及使用什么模式?

    默认运行时配置实现使用硬编码为true 的参数looseMatch。 javadoc中有描述

    可以选择“松散地”匹配模式。当结束 模式匹配 *[^*]*$(通配符、无通配符、通配符),如果 模式失败,它也被匹配,好像最后两个字符没有 存在。目标是支持传统的“*!*”语法,其中“!*” 是可选的。

    正如评论中提到的@Quaternion,带有paterrn * 的匹配器已添加到列表中。如前所述的任何其他内容。

    【讨论】:

    • 但是AdminAction.action中没有_却还是被*_*匹配到了,这真是让人困惑。
    • @RomanC 重点是模式*_*,正在被解析为*,不可能有这种行为。搜索“”已记录在案。
    • 非常感谢。您能告诉我您获得的 URL 以获取更多详细信息吗?
    • 我在网站上阅读了doc,但没有发现任何有用的东西,今天我在源代码中找到了。
    • XWork API 文档中还有 link
    猜你喜欢
    • 2011-07-10
    • 1970-01-01
    • 2023-03-25
    • 2018-06-12
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-10-04
    • 2014-01-11
    相关资源
    最近更新 更多