• 【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>
    
  • 相关阅读:
    Spring Cloud 网关服务 zuul 二
    spring cloud 2.x版本 Gateway动态路由教程
    spring cloud 2.x版本 Sleuth+Zipkin分布式链路追踪
    spring cloud 2.x版本 Gateway熔断、限流教程
    spring cloud 2.x版本 Gateway动态路由教程
    spring cloud 2.x版本 Gateway路由网关教程
    spring cloud 2.x版本 Hystrix Dashboard断路器教程
    spring cloud 2.x版本 Config配置中心教程
    [每天进步一点点]mysql笔记整理(三):索引
    [每天进步一点点]mysql笔记整理(二):事务与锁
  • 原文地址:https://www.cnblogs.com/haoworld/p/struts2-lan-jie-qi.html
Copyright © 2020-2023  润新知