Struts2拦截器

Posted 爱吃兔肉的保尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2拦截器相关的知识,希望对你有一定的参考价值。

一、概述

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

二、在Struts2中使用拦截器

2.1 步骤

  • 1.创建一个Interceptor 可以自定义一个类实现com.opensymphony.xwork2.interceptor.Interceptor

    • 在这个接口中有三个方法 init destroy intercept, intercept方法是真正拦截的方法。
    • 在intercept方法中如果要向下继续执行,通过其参数ActionInvocation调用它的invoke()方法就可以。
  • 2.声明一个Interceptor

    • 参考struts-default.xml文件中配置,在struts.xml文件中要自己声明一个interceptor
  • 3.在action中指定使用哪些拦截器.

    • 注意:只要显示声明使用了一个拦截器。那么默认的拦截器就不在加载。

2.2 分析拦截器原理

  • 源代码执行流程:

  • 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中就是通过递归完成所有的拦截调用操作.

2.3 关于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方法。

public class BookInterceptor extends MethodFilterInterceptor {

    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {

        // 1.得到session中的user
        User user = (User) ServletActionContext.getRequest().getSession()
                .getAttribute("user");

        if (user == null) {
            BookAction action = (BookAction) invocation.getAction(); // 得到当前拦截的action对象。

            action.addActionError("权限不足,请先登录");// 存储错误信息

            return Action.LOGIN;
        }

        return invocation.invoke();
    }

}
  • 2.在struts.xml文件中声明
<interceptors>
    <intercept name="" class="">
        <param name="includeMethods">add,update,delete</param>
        <param name="excludeMethods">search</param>
    </intercept>
</interceptors>

以上是关于Struts2拦截器的主要内容,如果未能解决你的问题,请参考以下文章

Fileuploader拦截器Struts2

Struts2拦截器浅解

Struts2学习:interceptor(拦截器)的使用

Struts2

Struts2

Struts2拦截器