Struts2通配符和它的各种问题总结

参考 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">

在这里插入图片描述
我只用了这个
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40803626/article/details/88686847