zoukankan      html  css  js  c++  java
  • 09-struts2的拦截器

    1.介绍拦截器:

    struts2拦截器使用的是AOP思想。 AOP的底层实现就是动态代理。
    拦截器 采用 责任链 模式
    * 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
    * 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行

    struts2中在struts-default.xml文件中声明了所有的拦截器。
    struts2框架默认使用的是defaultStack这个拦截器栈
    在这个拦截器栈中使用了18个拦截器。简单说,struts2框架
    在默认情况下,加载了18个拦截器。
    -----------------------------------------------------


    2..struts2中怎样使用拦截器



    问题:使用拦截器可以做什么?
    可以通过使用拦截器进行控制action的访问。例如,权限操作。



    怎样使用拦截器?

     

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

    在这个接口中有三个方法 init destory intercept, intercept方法是真正拦截的方法。

    在intercept方法中如果要向下继续执行,通过其参数ActionInvocation调用它的invoke()方法就可以。

        • 2.声明一个Interceptor

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

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

    <interceptor-ref name="my"/>

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

     

               注册默认拦截器:<interceptor-ref name="defaultStack"></interceptor-ref>

     


    3.分析拦截器原理

     

    源代码执行流程:

     

    • 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(先找到接口类打开,然后双击接口名选中,再按住ctrl+T就可以了).


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

     

    4.关于interceptor与Filter区别:(面试题)


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


    5.案例

    权限控制:

     

    • 1.login.jsp------>LoginAction------------->book.jsp

    登录成功,将用户存储到session。

    • 2.在book.jsp中提供crud链接。

    每一个连接访问一个BookAction中一个方法。

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

    • 3.怎样解决只控制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>

     

     

    6.案例代码

        

    login.jsp代码:

    <form action="${pageContext.request.contextPath }/login">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <input type="submit" value="登录">
        </form>

    loginAction代码:

    package cn.itcast.action;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class LoginAction extends ActionSupport {
        private String username;
        private String password;
        
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String login() {
            // TODO Auto-generated method stub
            if("tom".equalsIgnoreCase(username) && "123".equals(password)) {
                ServletActionContext.getRequest().getSession().setAttribute("user", username);
                return "success";
            }
            
            return "input";
        }
    }

    book.jsp代码:

      <a href="${pageContext.request.contextPath}/book_search">book search..</a>
        <a href="${pageContext.request.contextPath}/book_add">book add..</a>
        <a href="${pageContext.request.contextPath}/book_update">book update..</a>
        <a href="${pageContext.request.contextPath}/book_delete">book delete..</a>

    全部的struts.xml代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <interceptors>
                <interceptor name="my" class="cn.itcast.intercept.MyIntercept">
                    <param name="includeMethods">add,update,delete</param>
                    <param name="excludeMethods">search</param>
                </interceptor>
            </interceptors>
            <action name="login" class="cn.itcast.action.LoginAction" method="login">
                <result name="success">/book.jsp</result>
                <result name="input">/login.jsp</result>
            </action>
            <action name="book_*" class="cn.itcast.action.BookAction" method="{1}">
                <result name="login">/login.jsp</result>
                <interceptor-ref name="my">    </interceptor-ref>
           <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package> <constant name="struts.i18n.encoding" value="UTF-8"/> </struts>

     

    BookAction代码:

    package cn.itcast.action;
    
    public class BookAction {
        public String search() {
            // TODO Auto-generated method stub
            System.out.println("search..");
            return null;
        }
        public String add() {
            // TODO Auto-generated method stub
            System.out.println("add..");
            return null;
        }
        public String update() {
            // TODO Auto-generated method stub
            System.out.println("update..");
            return null;
        }
        public String delete() {
            // TODO Auto-generated method stub
            System.out.println("delete..");
            return null;
        }
    }

    权限拦截器代码:

    package cn.itcast.intercept;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
    
    public class MyIntercept extends MethodFilterInterceptor {
    
        @Override
        protected String doIntercept(ActionInvocation arg0) throws Exception {
            // TODO Auto-generated method stub
            String user = (String) ServletActionContext.getRequest().getSession().getAttribute("user");
            if(user == null) {
                return "login";
            }
            return arg0.invoke();//登录放行
        }
        
    }

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    基于物品属性的过滤
    第一个极小的机器学习的应用
    基于物品过滤的Slope One 算法
    【转】Python爬虫(1)_基本原理
    程序猿面试题集锦
    Django:popup弹出框简单应用实例
    【转】Python max内置函数详细介绍
    MySQL数据库(9)_MySQL数据库常用操作命令
    【转】Python的hasattr() getattr() setattr() 函数使用方法详解
    Git常用命令
  • 原文地址:https://www.cnblogs.com/1963942081zzx/p/6490446.html
Copyright © 2011-2022 走看看