struts2的拦截器原理

拦截器与过滤器的区别

一、filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;

二、filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;

三、filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);

四、filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤;

五、interceptor可以访问action上下文、值栈里的对象,而filter不能;

六、在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

 

Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截,Struts2 拦截器是可插拔的(在系统运行的时候可以配置与删除), 拦截器是 AOP 的一种实现.

拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用

struts的执行原理

 

strutsPrepareAndExecuteFilter有两层含义Prepare预处理 Execute执行

Prepare操作过滤器 init方法完成  -------- Dispacher  init方法

         * 加载struts配置文件,如果配置文件有错误,启动时就会报错

Execute操作过滤器 doFilter方法完成  ------ DispacherserviceAction 

          ActionProxy proxy =config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(

                    namespace, name, method,extraContext, true, false);

         为目标Action创建代理对象 ActionProxy 

     proxy.execute() ------  ActionInvocation.invoke  ----

          if (interceptors.hasNext()) {      

                            resultCode =interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

          }

          --- ActionInvocation.invoke 重复调用下一个拦截器 -----  resultCode = invokeActionOnly();

 

Interceptor接口

         每个拦截器都是实现了 com.opensymphony.xwork2.interceptor.Interceptor接口的 Java 类:

•    init: 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化

•    interecept: 每拦截一个动作请求, 该方法就会被调用一次.

•    destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次.

l  Struts 会依次调用程序员为某个 Action 而注册的每一个拦截器的 interecept 方法.

l  每次调用 interecept 方法时, Struts 会传递一个ActionInvocation 接口的实例.

l  ActionInvocation: 代表一个给定动作的执行状态, 拦截器可以从该类的对象里获得与该动作相关联的 Action 对象和 Result 对象. 在完成拦截器自己的任务之后, 拦截器将调用 ActionInvocation对象的 invoke方法前进到 Action处理流程的下一个环节.

l  还可以调用ActionInvocation 对象的 addPreResultListener方法给 ActionInvocation 对象 “挂” 上一个或多个PreResultListener 监听器. 该监听器对象可以在动作执行完毕之后, 开始执行动作结果之前做些事情

AbstractInterceptor 类实现了 Interceptor 接口. 并为 init, destroy 提供了一个空白的实现

 

自定义拦截器

 

拦截器都必须实现 Interceptor 接口 , 必须实现 intercept 方法

         java.lang.Stringintercept(ActionInvocation invocation)

         * intercept 方法类似 Filter 中 doFilter ,执行拦截后 , 调用 invocation.invoke 方法

        

自定义拦截器 也可以继承AbstractInterceptor      

写完拦截器后必须要进行配置

第一种配置(用的少)

                   <!-- 第一步 在struts.xml文件中注册权限控制拦截器 -->

                   <interceptors>

                            配置自己的拦截器,写上类名

                            <interceptorname="privilege"class="cn.itcast.interceptor.PrivilegeInterceptor"></interceptor>

                   </interceptors>

                  

                   <actionname="addEmployee" class="cn.itcast.action.AddEmployeeAction">

                            <result>/index.jsp</result>

                            <!-- 第二步,在Action访问中 配置拦截器 

                                     当Action 指定了使用拦截器后,默认拦截器会失效,因此先要先写上默认的拦截器栈

                            -->

                            <interceptor-refname="defaultStack"></interceptor-ref>

                            <interceptor-refname="privilege"></interceptor-ref>

                   </action>

第二种

                   <!-- 第一步 注册权限控制拦截器 -->

                   <interceptors>

                            <interceptorname="privilege"class="cn.itcast.interceptor.PrivilegeInterceptor"></interceptor>

                           

                            <!-- 定义了一个新的拦截器栈 -->

                            <interceptor-stackname="privilegeStack">

                                     <interceptor-refname="defaultStack"></interceptor-ref>

                                     <interceptor-refname="privilege"></interceptor-ref>

                            </interceptor-stack>

                   </interceptors>

 

                   <actionname="addEmployee"class="cn.itcast.action.AddEmployeeAction">

                            <result>/index.jsp</result>

                            <!-- 第二步,在Action访问中 配置拦截器 -->

                            <interceptor-refname="privilegeStack"></interceptor-ref>

                   </action>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值