java EE开发之Struts2第五章:拦截器

一.介绍拦截器:
  struts2拦截器使用的是AOP思想,AOP的底层实现就是动态代理。拦截器 采用 责任
链模式 ,在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行。
struts2中在struts-default.xml文件中声明了所有的拦截器。而struts2框架默认使用的是defaultStack这个拦截器栈。在这个拦截器栈中使用了18个拦截器。简单说,struts2框
架在默认情况下,加载了18个拦截器。常见的struts2拦截器

<interceptor-ref name=”modelDriven”/>模型驱动
<interceptor-ref name=”fileUpLoad”/>文件长传
<interceptor-ref name=”params”/>参数解析封装
<interceptor-ref name=”conversionError”/>类型转换错误
<interceptor-ref name=”validation”/>参数校验
<interceptor-ref name=”workflow”/>拦截跳转input视图

这里写图片描述

二.struts2中怎样使用拦截器
  在使用拦截器之前我们先搞清楚使用拦截器可以做什么?这个问题我觉得可以这样回答,可以通过使用拦截器进行控制action的访问。例如,权限操作。

1.怎样使用拦截器?
步骤1,创建一个Interceptor 可以自定义一个类实现
com.opensymphony.xwork2.interceptor.Interceptor
在这个接口中有三个方法 init destory intercept, intercept方法是真正拦截的方法。在intercept方法中如果要向下继续执行,通过其参数ActionInvocation 调用它的invoke()方法就可以。所以实际开发中只需要实现AbstractInterceptor类,提供intercept方法即可!

步骤2.声明一个Interceptor
在struts-default.xml文件中

<interceptors>
    <interceptor name="" class=""/>
</interceptors>
注意:我们要自己声明一个interceptor可以在struts.xml文件中声明。

步骤3.在action中指定使用哪些拦截器.

<interceptor-ref name="my"/>

注意:只要显示声明使用了一个拦截器。那么默认的拦截器就不在加载,所以当我们要使用自己的拦截器,一般要手动将默认拦截器显示指定,并且我们将所有拦截器定义到拦截器栈中这样便于管理和拦截器的组合。

<interceptor-stack name="test">
       <interceptor-ref name="myInterceptor"></interceptor-ref>
       <interceptor-ref name="mehtodInterceptor"></interceptor-ref>
</interceptor-stack>

三.分析拦截器原理
源代码执行流程:
1.在StrutsPrepareAndExecuteFilter中查找
在doFilter方法内有一句话 execute.executeAction (request, response, mapping) 执行
Action操作.
2.在executeAction执行过程中会访问Dispatcher类中的serviceAction,在这个方法中会
创建一个ActionProxy proxy =
config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace,
name, method, extraContext, true, false);这就是我们的Action的代理对象
3.查看ActionInvocation,查看其实现类 DefaultActionInvocation.
在其invoke方法中

if (interceptors.hasNext()) {//判断是否有下一个拦截器.
            final InterceptorMapping interceptor = interceptors.next(); //得到一个拦截器
            String interceptorMsg = "interceptor: " + interceptor.getName();
            UtilTimerStack.push(interceptorMsg);
            try {
//调用得到的拦截器的拦截方法.将本类对象传递到了拦截器中。
                resultCode = 
interceptor.getInterceptor().intercept(DefaultActionInvocation.this); 
            }finally {
                UtilTimerStack.pop(interceptorMsg);
            }
        } 

通过源代码分析,发现在DefaultActionInvocation中就是通过递归完成所有的拦截调用
操作.
这里写图片描述

四.关于interceptor与Filter区别:
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调
用一次。

五.案例

权限控制:
1.login.jsp——>LoginAction————->book.jsp
登录成功,将用户存储到session。

2.在book.jsp中提供crud链接。
每一个连接访问一个BookAction中一个方法。

要求:对于BookAction中的add,update,delete方法要求用户必须登录后才可以访问。
search无要求。

补充:怎样解决只控制action中某些方法的拦截?
1.创建类不在实现Interceptor接口,而是继承其下的一个类.MethodFilterInterceptor
不用在重写intercept方法,而是重写 doIntercept方法。

2.在struts.xml文件中声明

<interceptors>
    <intercept name="" class="">
    <param name="includeMethods">add,update,delete</param>
        <param name="excludeMethods">search</param>
    </intercept>
</interceptors>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值