struts2源码系列(1)--ActionConfig(对应struts.xml <action>标签)

1.介绍

这里都是以spring4.0以上讲解

ActionConfig封装了一个Action配置,对应了struts.xml配置<action>标签,属性了这个实体类,我们才能更好的配置struts.xml,也能清楚的了解问什么要这么配置

2.ActionConifg

2.1关键属性

    public static final String DEFAULT_METHOD = "execute";//action默认的执行方法
    public static final String WILDCARD = "*";

    protected List<InterceptorMapping> interceptors; //这个action的拦截器,只要是进入这个action,拦截器就会执行
    protected Map<String,String> params;//需要保存的一些参数
    protected Map<String, ResultConfig> results;//结果映射
    protected List<ExceptionMappingConfig> exceptionMappings;//异常映射配置
    protected String className;//action对应的class---对应<action class=""> class属性  这个class可以是真正的class属性,
也可以是一个名称,如果是一个名称,说明这个action交给了spring管理创建
    protected String methodName;//这个action对应的方法--对应<action method="">method属性
    protected String packageName;//所在包的名称--<package name="">对应name属性
    protected String name;//action的名称---对应<action name=""> name 属性
    protected Set<String> allowedMethods;//允许访问的方法--如果struts.xml中配置的一个method是一个通配符形式比如{1},
 但是没有配置allowedMethod,那么即便匹配成功了,也是不能访问的 对应<allowed-methods>

2.2关键方法

boolean isAllowedMethod(String method) 判断方法是否允许访问

判断条件:

如果allowedMethods大小等于1,并且allowedMethods中的内容是*表示所有方法都允许,则直接返回true

否则,要么这个method等于execute,要么allowedMethods contains这个方法

2.3ActionConfig创建流程

项目的启动的时候,struts核心组件会解析struts.xml,然后解析出来<action>标签组成ActionConfig对象,一个action标签就对应一个ActionConfig对象

2.3.1没有通配符的配置

<package name="test" namespace="/test" extends="struts-default">
      <!-- action配置 -->
      <action name="test" class="cn.dhcc.action.TestAction" method="test">
         <result name="index">/index.jsp</result>
        <!--  <exception-mapping result="" exception=""></exception-mapping>
         <interceptor-ref name=""></interceptor-ref>
         <param name=""></param> -->
      </action>
   </package>

封装成ActionConfig对象后:

name:test

className:cn.dhcc.action.TestAction

methodName:test

allowedMethods:空的set,这个不用配置,这不是通配符匹配,所以直接用methodName对应的方法,因此这个属性此时是不起作用的

packageName:test

results:是一个map,里面非空

interceptors:空的map,当然可以配置

params:空的map,当然可以配置

exceptionMappings:空的map,当然可以配置

2.3.2 有通配符的配置

<package name="test1"  extends="struts-default" namespace="/">
      <!-- action配置 -->
      <action name="*Action" class="loginAction" method="{1}">
         <result name="index">/index.jsp</result>
         <allowed-methods>login,logout</allowed-methods>
      </action>
   </package>

解析后,生成的ActionConfig对象

name:*Action

className:loginAction---由spring管理的bean

methodName:{1} ----通配符

allowedMethods:set集合  将login logout以逗号分隔后生成set集合

packageName:test1

results:是一个map,里面非空

interceptors:空的map,当然可以配置

params:空的map,当然可以配置

exceptionMappings:空的map,当然可以配置

2.4解析流程

这里先大概介绍一下Action解析:

一个请求发出来以后,比如http://xxxx:8080/web/test1/loginAction.action?age=10&name=lisi

1.首先从requet对象中得到请求的uri, /test1/loginAction.action

2.然后去掉后缀,根据struts配置的允许的后缀名来切割,留下/test1/loginAction

3.循环PackageConfig配置(下节介绍),根据namespace判断,最后解析出来namespace  /test1,action的名称就是loginAction

4.解析action的名称,看看是不是有!,如果有也表示动态方法调用的,切割!前面的作为action名称,后面作为方法名称,当然对于这个例子,肯定不会执行这行代码

到这一步:已经得到了一个ActionMapping对象,其中name='loginAction', namespace='/', method='null', extension='action', params=null, result=null

5.接下来就是创建代理,创建代理是有一步就是解析action对应的方法,首先根据命名空间,还有action的名称找到对应的ActionConfig对象,这里查找ActionConfig时稍微有些复杂,首先根据命名空间,action名称进行精确查找,如果找不到,然后根据命名空间,找到满足条件的所有ActionConfig,然后循环,通过匹配查找,如果是动态匹配的话,比如这个例子中,就会解析出参数,0=loginAction 1=login ,然后再通过对应的ActionConfig(属性method={1}),解析出来对应的方法是login。解析出来login后,还要判断这个动态的方法是否允许访问,通过isAllowedMethod()方法判断。注意这里不仅仅会转换action方法,还包括result只要用到了动态匹配参数,都会进行转换。这样就通过配置的ActionConfig解析出来了一个真正运行时的ActionConfig,里面都是精确的属性值

这一步,也说明了,为什么配置了了精确的action时,allowedMethods就没作用了,那就是因为,精确查找的话,直接就能找到配置对应的action,不会再去验证方法是否允许被访问了

6.第5步,找到了action---loginAction(这其实是bean的名称),还有对应的方法名login。接下来就是通过反射创建action类,然后调用对应的方法

3.总结---struts中action的配置方式

struts2中action的配置请求有三种方式

1.精确配置,一个action对应一个请求方法

如:<action name="test" class="cn.dhcc.action.TestAction" method="test"></action>

这样一个action就仅仅对应一个处理方法

http://xxxxx:8080/web/test/test.action----对应就是TestAction的test()方法

这种方式比较麻烦,一个方法对应一个action配置

这种方式不用配置allowedMethods,因为,请求的方法test就等于了ActionConfig的methodName属性了

2.模糊匹配,一个action对应多个请求方法,通过占位符来实现

如:<action name="*Action" class="loginAction" method="{1}">

请求http://xxxxx:8080/web/test/loginAction.action----对应就是loginAction的login()方法

    http://xxxxx:8080/web/test/logoutAction.action----对应就是loginAction的logout()方法

这种方式可以动态的指定请求方法,但可读性不好,因为占位符是name的一部分,这么以来就会出现loginAction logoutAction--无法准确的知道到底是哪个action类

这种方式一定要配置allowedMethods指明可以动态访问的方法,因为,动态方法不会等于ActionConfig的methodName属性又不等于默认的execute,只能通过是否配置了allowedMethods来判断可访问性

3.模糊匹配,一个action对应多个请求方法,通过!感叹号来实现

如:<action name="testAction" class="cn.dhcc.action.TestAction" ></action> 配置action的时候,不指明方法名。请求的时候指定

如:http://xxxxx:8080/web/test/testAction!test.action----对应就是TestAction的test()方法

http://xxxxx:8080/web/test/testAction!list.action----对应就是TestAction的list()方法

这种方式也可以动态的指定请求方法,并且可读性好,因为一看就知道test list都是同一个action类,这对于一个模块的多个方法(一个模块一个类来表示),可以准确的知道所在的是哪个模块,推荐使用

这种方式也一定要配置allowedMethods指明可以动态访问的方法,因为,动态方法不会等于ActionConfig的methodName属性又不等于默认的execute,只能通过是否配置了allowedMethods来判断可访问性

 

转载于:https://my.oschina.net/yibuliushen/blog/737869

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值