参考 https://blog.csdn.net/Holmofy/article/details/78387958
错误总结在后面
*通配符的使用
<action name="The_*" class="action.{1}Action" method="{1}">
<result name="success">
</result>
<result name="failure">/mainMenu.jsp</result>
<result>{1}.jsp</result>
</action>
<action name="*Action" class="action.{1}Action" method="{1}">
</action>
匹配一个或者多个字符,允许匹配所有以Action结束的url。
如/loginAction.action,loginAction
出现多个的时候,{1}可以代表第一个*,{2}可以代表第二个。
<action name="/edit*" class="struts.webapp.example.Edit{1}Action">
<result name="failure">/mainMenu.jsp</result>
<result>{1}.jsp</result>
</action>
上面name属性中的*通配符就是允许匹配任意以/edit开头的url,比如/editSubscription, /editRegistration,但是需要注意的是/editSubscription/add这种url是无法匹配的。
在标签的其他属性中,甚至子标签中以及result的子标签都可以使用{n}这种方式去替换url映射中由通配符表示的部分,其中n的范围是0到9,特殊地,当n=0时,表示完整的请求路径。
比如/edit*匹配/editRegistration请求,那么{1}就是Registration,{0}就是/editRegistration(这方面和正则表达式类似)。
注意下面的
<action name="List*s" class="actions.List{1}s">
<result>list{1}s.jsp</result>
</action>
当url为ListAccounts,上面的配置会正常运行。当url为ListSponsors时,由于ListSponsors中间也出现了s,所以最终会得到下面的匹配结果:
<action name="ListSpons" class="actions.ListSpons">
<result>listSpons.jsp</result>
</action>
*号最好不要出现在中间
** 通配符
前面说到/edit通配符无法匹配/editSubscription/add这样的url。如果确实需要匹配这种url可以使用两个号, 也就是/edit**。
注意:如果需要让Action的name属性包含/,需要配置一个常量:
<constant name="struts.enable.SlashesInActionNames" value="true"/>
虽然能够让Action的name包含/,但Struts2官方并不推荐使用这种配置(因为有副作用),可以参看Struts2官网对Action name包含/的讨论:https://issues.apache.org/jira/browse/WW-1383
另外如果需要对Action name中能出现的字符进行限制,可以配置如下变量:
<constant name = “struts.allowed.action.names” value = “[a-z{}]” */>
上面这中使用*或?的通配符模式有很多名字,有人把它叫做glob匹配模式,也有人把它叫做Ant-style…
命名空间的配置
https://blog.csdn.net/Holmofy/article/details/78387958
虽然不推荐Action的name属性包含/,但是对于使用/进行模块划分有更好的解决方案——package的namespace属性。
Struts2中,package标签的namespace属性是用来细分项目模块的,比如:
<!-- 没有配置namespace,则为默认命名空间 -->
<package name="default">
<action name="foo" class="mypackage.simpleAction">
<result name="success" type="dispatcher">greeting.jsp</result>
</action>
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar1.jsp</result>
</action>
</package>
<!-- 配置namespace为"/",则为根命名空间 -->
<package name="mypackage1" namespace="/">
<action name="moo" class="mypackage.simpleAction">
<result name="success" type="dispatcher">moo.jsp</result>
</action>
</package>
<!-- 配置namespace为"/barspace",是精确命名空间 -->
<package name="mypackage2" namespace="/barspace">
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar2.jsp</result>
</action>
</package>
命名空间的匹配优先级为:精确命名空间 > 根命名空间 > 默认命名空间
动态方法调用
除了通配符方法,Struts2还提供了一种更便捷的方式进行Action的方法映射。
动态方法调用(Dynamic Method Invocation)。不过官方文档中说,DMI方式存在安全性问题,所以Struts2中默认把这个功能关闭了(default.property文件中struts.enable.DynamicMethodInvocation=false),如果需要使用需要设置常量将该功能打开。
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<action name="use!*" class="cn.hff.struts.UserAction" method="{1}">
...
</action>
报错
There is no Action mapped for namespace [/users] and action name [User_login] associated
with context path [/Struts2AndHibernate].
解决method中的问题
https://blog.csdn.net/Holmofy/article/details/78387958
<action name="The_*" class="action.{1}Action" method="{1}">
<result name="success">
</result>
</action>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
当使用动态调用方法时(action名 + 感叹号 + 方法名进行方法调用),需要将其属性改为true,
当使用通配符调用语法时,建议将其属性改为false(struts2.5.2中默认是false)
当我们需要将其属性改成false时,
只在struts.xml配置文件中加入此句即可修改属性
1.使用通配符方法进行映射,和使用!符号的“动态方法调用”可能会重叠,需要设置一个常量来禁用动态方法调用(Struts2.5默认是禁用状态):
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
2.对于Struts2.3之前的版本可以不配置<allowed-methods>
,但是对于之后的版本,如果不配置<allowed-methods>
将会出现如下异常:
Struts has detected an unhandled exception:
Message:There is no Action mapped for namespace [/] and action name [user_login] associated with context path
1. Action里面添加<allowed-methods>
<allowed-methods>delete,update,insert,select</allowed-methods>
2. Package里面添加<allowed-methods>
<global-allowed-methods>regex:.*</global-allowed-methods>
或者
//设定全局允许通行的方法
<global-allowed-methods>method1,method2</global-allowed-methods>
<global-allowed-methods>execute,input,back,cancel,browse,save,delete,list,index</global-allowed-methods>
4.注解加在action类上
@AllowedMethods("method")
public class TestAction extends ActionSupport {
......
}
3. 关闭严格方法调用
struts2从2.5版本开始,为了提升安全性,默认开启了严格的方法调用。
如果要使用通配符*,必须在package中设置 strict-method-invocation=“false”,代码如下:
<package name = "default" namespace="/" extends="struts-default" strict-method-invocation="false">
等于说放弃了新引进的DMI机制,一劳永逸,但有风险(不过想想原来都是这样用的……
在Struts2.3中在package标签中添加了一个属性来限制DMI,该选项告诉Struts2框架拒绝所有未通过method属性配置或者
<allowed-methods>
标签标明的方法。
在Struts2.5中不仅仅限制了DMI的调用,还对Action的可使用的方法进行了限制,也就是默认开启了strict-method-invocation
选项(在struts-default.xml文件中可以看到)
最后一个坑,遇到红字怎么办,但是有解决不了。仔细看看你的struts.xml的版本有没有错
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
我只用了这个