zoukankan      html  css  js  c++  java
  • (十一)拦截器基础

    二、自定义拦截器应用

      2.1  第一个自定义拦截器

    • index.jsp
    <body>
        <a href="<%=path%>/Interceptor/InterceptorAction">此页面跳转的action会被自定义拦截器拦截</a>
    </body>
    • struts.xml
       <package name="default" namespace="/Interceptor" extends="struts-default">
                        <!-- 定义拦截器 -->
            <interceptors>
                <interceptor name="interceptorTest" class="interceptor.InterceptorTest"></interceptor>
            </interceptors>
            
            <action name="InterceptorAction" class="action.InterceptorAction">
                <result name="re">/index_2.jsp</result>
                    <!-- 引用拦截器 -->
                <interceptor-ref name="interceptorTest"></interceptor-ref>
            </action>
        </package>
    • InterceptorTest.java(编写拦截器的代码)
    package interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    
    /**
     * 自定义的拦截器
     * @author Administrator
     *
     */
    
    public class InterceptorTest implements Interceptor {
    
        public void destroy() {
        }
    
        public void init() {
        }
    
        public String intercept(ActionInvocation actionInterceptor) throws Exception {
        
            System.out.println("我是第一次自定义拦截器");
            /*
             * 让Action的方法执行,并返回action的结果。
             * ActionInvocation。invoke()方法会调用下一个拦截器 或 执行下一个Action,如果是执行actino就返回action的result值。
             * 而ActionInvocation。getResultCode()只获得action的result返回值并不执行action。
             */
            String next=actionInterceptor.invoke();
            return null;
        }
    
    }
    • InterceptorAction.java(被拦截的action)
    package action;
    
    public class InterceptorAction {
        public String execute(){
            
            System.out.println("我是action");
            return "re";
        }
    }
    • index_2.jsp(action执行成功后跳转的页面)
    <body>
        我是跳转后的页面
    </body>

    结果:

    查看后台可知,拦截器中的方法比action的方法先执行,说明拦截成功。

      2.2  拦截器栈:如果拦截器很多的话,可以把这些拦截器放到拦截器栈里,在action类中引用拦截器栈,拦截器栈中的每个拦截器会按顺序对action进行拦截。

    如上例,再加一个拦截器。

    • struts.xml
      <package name="default" namespace="/Interceptor" extends="struts-default">
                        <!-- 定义拦截器 -->
            <interceptors>
                <interceptor name="interceptorTest" class="interceptor.InterceptorTest"></interceptor>
                <interceptor name="interceptor_two" class="interceptor.Interceptor_two"></interceptor>
                        <!-- 定义拦截器栈,引入拦截器 -->
                <interceptor-stack name="mystack">
                <interceptor-ref name="interceptor_two"></interceptor-ref>
                    <interceptor-ref name="interceptorTest"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            
            
            <action name="InterceptorAction" class="action.InterceptorAction">
                <result name="re">/index_2.jsp</result>
                    <!-- 引用拦截器栈-->
                <interceptor-ref name="mystack"></interceptor-ref>
            </action>
        </package>
    • 解析:当访问url为"/工程名/Interceptor/InterceptorAction"这个action 的时候,此时这个action里引用了拦截器栈,拦截器栈里有两个拦截器,会按顺序逐一地对action进行拦截

    2.3  默认拦截器

    •  struts.xml
      <package name="default" namespace="/Interceptor" extends="struts-default">
                        <!-- 定义拦截器 -->
            <interceptors>
                <interceptor name="interceptorTest" class="interceptor.InterceptorTest"></interceptor>
                <interceptor name="interceptor_two" class="interceptor.Interceptor_two"></interceptor>
                    <!-- 
                设定哪一个拦截器或者拦截器栈为默认的
                1:当Action中没有使用interceptor-ref引用时,默认拦截器将会起作用。如果Action中配置interceptor-ref,那么
                  默认的拦截器将不起作用    
                2:将设定default-interceptor-ref为自定义的拦截器后,struts-default.xml中定义的默认拦截器将不起作用。
                  所有Struts的功能将不能使用。要将defaultStack拦截器栈引用到自定义到拦截器栈中        
                3:其他的package要使用自定义的拦截器,将package做一个继承即可。    
            -->
                <interceptor-stack name="mystack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="interceptor_two"></interceptor-ref>
                    <interceptor-ref name="interceptorTest"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="mystack"></default-interceptor-ref>
            
            <action name="InterceptorAction" class="action.InterceptorAction">
                <result name="re">/index_2.jsp</result>
            </action>
        </package>

               1:当Action中没有使用interceptor-ref引用时,默认拦截器将会起作用。如果Action中配置interceptor-ref,那么
                  默认的拦截器将不起作用
                2:将设定default-interceptor-ref为自定义的拦截器后,struts-default.xml中定义的默认拦截器将不起作用。
                  所有Struts的功能将不能使用。要将defaultStack拦截器栈引用到自定义到拦截器栈中。 
                3:其他的package要使用自定义的拦截器,将package做一个继承即可。

               4. Struts2在struts-default包中定义了一个默认的拦截器栈引用:defaultStack。因此当我们定义的包继承自struts-default包时也继承了它的默认拦截器引用:defaultStack,当我们不为Action显式的应用拦截器,则defaultStack栈会起作用。

     2.4   用自定义拦截器实现登录验证

    •  servlet里用过滤器实现登录验证,而struts2可以用拦截器来实现登录验证,但是在开发中,一般使用过滤器来实现登录验证,因为拦截器只能拦截action。

    •  index.jsp
    <body>
            <h2>登录系统</h2>
            <form action="interceptor/main" method="post">
    
            用户名:<s:textfield name="username"></s:textfield><br/>&nbsp;码:<s:password name="password"></s:password>
            <s:submit value="提交"></s:submit>
            </form>
    </body>
    • sturts.xml(如果没有<interceptor-ref name="defaultStack"></interceptor-ref>的话,那么在action中就无法得到表单的值,这个功能是默认拦截器引用:defaultStack的功能之一)
      <package name="default" namespace="/interceptor" extends="struts-default">
            <interceptors >
                <interceptor name="login" class="interceptor.LoginInterceptor"></interceptor>
            </interceptors>
     
               <action name="main" class="action.GoMainAction">
               <interceptor-ref name="defaultStack"></interceptor-ref>
               <interceptor-ref name="login"></interceptor-ref>
                   <result name="main">/index_2.jsp</result>
               </action>
        </package>
    •  GoMainAction.java
    package action;
    
    import javax.servlet.http.HttpSession;
    
    import org.omg.CORBA.Request;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import actionUtil.BaseAction;
    
    public class GoMainAction extends BaseAction{
        /*
         * 在action中获取表单值的前提是必须在struts.xml中引用默认拦截器引用:defaultStack
         */
        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 execute(){
    
            if((this.username).equals("admin")){
                if((this.password).equals("123")){
                    HttpSession session=request.getSession();
                    session.setAttribute("login", "ok");
                    return "main";
                    
                }else{
                    System.out.println("密码错误");
                    return null;
                }
                
            }else{
                
                System.out.println("用户名错误");
                return null;
            }
        }
    }
    • LoginInterceptor.java
    package interceptor;
    
    import java.io.PrintWriter;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    import com.opensymphony.xwork2.util.ValueStack;
    
    import action.GoMainAction;
    
    public class LoginInterceptor  implements Interceptor{
    
        public void destroy() {
        }
    
        public void init() {
        }
    
        public String intercept(ActionInvocation actionInvocation) throws Exception {
          
            Object action=actionInvocation.getAction();  //拿到被拦截的action对象
            ActionContext context=actionInvocation.getInvocationContext(); //拿到action的广义值栈。
            HttpServletRequest request=ServletActionContext.getRequest();  //拿到request对象
            HttpServletResponse response = ServletActionContext.getResponse();      //拿到response对象
                
            Map<String,Object> sessionMap=context.getSession();
            
            //    ValueStack valuestack=context.getValueStack();  //拿到action的狭义值栈。
            
            if(action.getClass().equals(GoMainAction.class)){
                //如果是验证登录的action,。则不进行拦截
                actionInvocation.invoke();
                
                 return null;
            }else{
        
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            String loginURL = request.getContextPath() + "/index.jsp";
            out.println("<script language='javascript'>");
            out.println("window.alert('您还未登录,或者登录已超时,请重新登录');");
            out.println("window.location.href = '" + loginURL + "';");
            out.println("</script>");
            
            return null;
            }
        }
    
    }
    • index_2.jsp
    <body>
        登录成功
    </body>
    • 用拦截器实现登录验证的问题: 1.  只能拦截action而无法拦截页面,也就是说无法拦截未登录用户访问需要登录的页面。

     2.5  利用拦截器实现监听程序运行效率(监听每个方法的运行时间,时间越长代表效率越低)

    •  index.jsp
    <body>
            <a href="interceptor/TestAction!one">方法1的运行效率</a>
            <a href="interceptor/TestAction!two">方法2的运行效率</a>
    </body>
    • struts.xml
     <package name="default" namespace="/interceptor" extends="struts-default">
        <interceptors>
            <interceptor name="test" class="interceptor.TestInterceptor"></interceptor>    
        </interceptors>
        
            <action name="TestAction" class="action.TestAction">
             <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="test"></interceptor-ref>
            </action>
        </package>
    • TestAction.java
    package action;
    
    public class TestAction {
        public String execute(){
            return null;
        }
        /**
         * 要测试的方法1
         * @return
         */
        
        public String one(){
            System.out.println("运行one方法");
        return null;    
        }
        /**
         * 要测试的方法2
         * @return
         */
        public String two(){
            System.out.println("运行two方法");
            try {
                Thread.sleep(6000);  //停留6秒
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            return null;
        }
    }
    • TestInterceptor.java(拦截器)
    package interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    import com.opensymphony.xwork2.util.ValueStack;
    
    public class TestInterceptor implements Interceptor{
    
        public void destroy() {
        }
    
        public void init() {    
        }
    
        public String intercept(ActionInvocation actionInvocation) throws Exception {
            
            Object obj=actionInvocation.getAction();  //获取正在拦截的对象
            ActionContext actionContext=actionInvocation.getInvocationContext(); //获取被拦截action的上下文对象
            ValueStack valuestack=actionContext.getValueStack();  //获取action的狭义值栈
            
            HttpServletRequest request = ServletActionContext.getRequest(); //获取erquest对象
            StringBuffer requestURL=request.getRequestURL();  //获取超时方法的URL
            
            //让action方法执行,并测试
            long start=System.currentTimeMillis();  //获取方法执行前的时间
            actionInvocation.invoke();  //执行方法
            long end=System.currentTimeMillis();   //获取方法执行后的时间
            
            int  diffSecond = (int) ((end - start) / 1000);  //获取方法总共执行时间差
            if(diffSecond >5){
                System.out.println("requestURI= " + requestURL +",间隔时间= "+diffSecond);  //如果方法执行时间超过5秒就把这个URL打印出来
            }  
            return null;
        }
    
    }

    结果:

    • 如结果,这样我们就把那些运行了很久的方法找了出来。
  • 相关阅读:
    Intellij IDEA 使用Spring-boot-devTools
    Intellij IDEA 使用Spring-boot-devTools
    Swift-Realm数据库的使用详解
    Maven快速上手
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    2019数据技术嘉年华主会场,数据英雄荟萃一堂共论道
    在 AWTK 中 如何让文本滚动起来
    数据库高可用架构了解一下
    session和token的区别
  • 原文地址:https://www.cnblogs.com/shyroke/p/6606624.html
Copyright © 2011-2022 走看看