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

    Struts2中的拦截器(特别重要)

          1、拦截器的重要性

                         Struts2中的很多功能都是由拦截器完成的。比如:servletConfig,staticParam,params,modelDriven等等。

                         AOP编程思想的一种应用形式。

          2、拦截器的执行时机:

                        

          3、自定义拦截器

               3.1、拦截器的类试图(初级版本):

            

               3.2、编写步骤:

                         a、编写一个类,继承AbstractInterceptor类或者实现Interceptor接口。重写intercept方法。    

     1 package com.itheima.web.interceptor;
     2 
     3 import com.opensymphony.xwork2.ActionInvocation;
     4 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
     5 /**
     6  * 自定义拦截器
     7  *     第一步:创建一个普通类,继承AbstractInterceptor,实现抽象方法intercept
     8  *  第二步:在struts.xml中配置拦截器
     9  *       1.声明拦截器
    10  *          <interceptors>
    11                 <interceptor name="demo1Interceptor" class="com.itheima.web.interceptor.Demo1Interceptor" />
    12             </interceptors>
    13          2.使用拦截器
    14              <!-- 使用自定义拦截器:当配置了任何一个拦截器,默认的拦截器栈就不会在工作了 -->
    15             <interceptor-ref name="demo1Interceptor"></interceptor-ref>
    16  * @author zhy
    17  *
    18  */
    19 public class Demo1Interceptor extends AbstractInterceptor {
    20 
    21     public String intercept(ActionInvocation invocation) throws Exception {
    22         System.out.println("Demo1Interceptor拦截器:拦截了-执行动作方法之前");
    23         //放行:如果有下一个拦截器,就前往下一个拦截器,如果没有了,就到达动作方法
    24         String rtValue = invocation.invoke();//就是结果视图的名称
    25         System.out.println("Demo1Interceptor拦截器:拦截了-执行动作方法之后");
    26         return rtValue;
    27     }
    28 
    29 }
    MyInterceptor1

                         b、配置拦截器:注意拦截器必须先声明再使用

                     注意: 在xml中配置了任何一个拦截器,默认的拦截器就不会再给我们工作了,要重新配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE struts PUBLIC
     3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
     4     "http://struts.apache.org/dtds/struts-2.3.dtd">
     5 <struts>
     6     <constant name="struts.devMode" value="true" />
     7     <package name="p1" extends="struts-default">
     8         <!-- 声明自定义拦截器 -->
     9         <interceptors>
    10             <interceptor name="demo1Interceptor" class="com.itheima.web.interceptor.Demo1Interceptor"></interceptor>
    11             <interceptor name="demo2Interceptor" class="com.itheima.web.interceptor.Demo2Interceptor"></interceptor>
    12         </interceptors>
    13         <action name="action1" class="com.itheima.web.action.Demo1Action" method="save">
    14             <!-- 使用自定义拦截器:当配置了任何一个拦截器,默认的拦截器栈就不会在工作了 .
    15                 当有多个拦截器的时候,是由引用配置决定执行的顺序 。 注意:执行顺序与声明无关-->
    16             <interceptor-ref name="demo2Interceptor"></interceptor-ref>
    17             <interceptor-ref name="demo1Interceptor"></interceptor-ref>
    18             <result name="success">/demo1.jsp</result>
    19         </action>
    20     </package>
    struts.xml

               3.3、执行顺序

                              见前面的执行时机图

               3.4、多个拦截器的执行顺序

                        在动作方法执行之前, 拦截器执行顺序与配置(不是声明)顺序正相关

           在动作方法执行之后, 拦截器执行顺序与配置(不是声明 )顺序负相关

               3.5、intercept方法的返回值

                           return      invocation.invoke();   返回的就是 结果视图(seccess,input,error等)

          4、拦截器的应用:

                4.1、检查登录的拦截器案例

                          配置文件:

                        

     1 <!-- 使用自定义拦截器,检查登录。最基本的配置方式。
     2          其中存在的问题:
     3              当我们使用了自定义拦截器之后,默认的拦截器栈就不再工作了 -->
     4     <package name="p2" extends="struts-default">
     5         <interceptors>声明拦截器
     6             <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
     7         </interceptors>
     8         <global-results>全局结果视图
     9             <result name="input">/login.jsp</result>数据回显的结果视图
    10         </global-results>
    11         用户登录时,不需要检查登录的拦截器工作
    12         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    13             <result type="redirectAction">showMain</result>
    14         </action>
    15         前往主页的动作名称,需要检查登录的拦截器工作
    16         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    17             <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    18             <result>/main.jsp</result>
    19         </action>
    20         前往另一个页面的动作名称,需要检查登录的拦截器工作
    21         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    22             <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    23             <result>/otherpage.jsp</result>
    24         </action>
    25     </package>
    struts.xml

                         动作类:

                              

     1 package com.itheima.web.action;
     2 
     3 import javax.servlet.http.HttpSession;
     4 
     5 import org.apache.struts2.ServletActionContext;
     6 
     7 import com.opensymphony.xwork2.ActionSupport;
     8 
     9 public class Demo2Action extends ActionSupport {
    10     
    11     
    12     /**
    13      * 用户登录的方法
    14      * @return
    15      */
    16     public String login(){
    17         HttpSession session = ServletActionContext.getRequest().getSession();
    18         session.setAttribute("user", "test");
    19         return SUCCESS;
    20     }
    21     
    22 
    23     
    24     /**
    25      * 无论是显示主页还是显示另一个页面都执行此方法,
    26      * 返回成功
    27      */
    28     public String execute(){
    29         return SUCCESS;
    30     }
    31 }
    动作类

                         拦截器:

                            

     1 package com.itheima.web.interceptor;
     2 
     3 import javax.servlet.http.HttpSession;
     4 
     5 import org.apache.struts2.ServletActionContext;
     6 
     7 import com.opensymphony.xwork2.ActionInvocation;
     8 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
     9 /**
    10  * 检查登录的拦截器,初级版本
    11  * @author zhy
    12  *
    13  */
    14 public class CheckLoginInterceptor extends AbstractInterceptor {
    15 
    16     public String intercept(ActionInvocation invocation) throws Exception {
    17         //1.获取HttpSession
    18         HttpSession session = ServletActionContext.getRequest().getSession();
    19         //2.获取session域中的登录标记
    20         Object obj = session.getAttribute("user");
    21         //3.判断是否有登录标记
    22         if(obj == null){
    23             //用户没有登录
    24             return "input";
    25         }
    26         //4.用户登录了,放行
    27         String rtValue = invocation.invoke();
    28         return rtValue;
    29     }
    30 
    31 }
    拦截器,形式1

                         页面:

                        

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5     <head>
     6         <title>主页:检查登录的拦截器</title>
     7     </head>
     8     <body>
     9         <%--要想来到本页面(主页),必须得先登录 --%>
    10         主页<hr/>
    11         <a href="${pageContext.request.contextPath}/showOther.action">访问另一个页面</a>
    12     </body>
    13 </html>
    主页
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5     <head>
     6         <title>用户登录</title>
     7     </head>
     8     <body>
     9         <form action="${pageContext.request.contextPath}/login.action" method="post">
    10             用户名:<input type="text" name="username"/><br/>
    11             密码:<input type="password" name="password"/><br/>
    12             <input type="submit" value="登录"/>
    13         </form>
    14     </body>
    15 </html>
    login
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5     <head>
     6         <title>另一个页面</title>
     7     </head>
     8     <body>
     9         另一个页面
    10     </body>
    11 </html>
    otherpage

               4.2、案例中的问题

                                问题:由于我们写了自己的拦截器,默认的拦截器不起作用了。

                         解决办法:

                                a、把默认拦截器加入到配置文件中

                               

     1 <!-- a.针对上面的问题,我们的解决办法是,把默认的拦截器栈也配置进来.
     2     <package name="p2" extends="struts-default">
     3         <interceptors>
     4             <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
     5         </interceptors>
     6         <global-results>
     7             <result name="input">/login.jsp</result>
     8         </global-results>
     9         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    10             <result type="redirectAction">showMain</result>
    11         </action>
    12         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    13             加入自定义拦截器,和默认的拦截器栈
    14             <interceptor-ref name="defaultStack"></interceptor-ref>
    15             <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    16             <result>/main.jsp</result>
    17         </action>
    18         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    19             加入自定义拦截器,和默认的拦截器栈
    20             <interceptor-ref name="defaultStack"></interceptor-ref>
    21             <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    22             <result>/otherpage.jsp</result>
    23         </action>
    24     </package>-->
    struts.xml

                         ba中暴露的问题:当有多个拦截器时,需要改写的地方非常多。

                                解决办法:抽取公共的包,把全局配置放入公共包中。

                        

     1 <!-- b. a中存在的弊端,当如果需要拦截的动作很多时,写起来很繁琐
     2     <package name="p2" extends="struts-default">
     3         <interceptors>
     4             <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
     5             定义一个拦截器栈,把我们自定义的拦截器和默认的拦截器栈放到一起.
     6             <interceptor-stack name="myDefaultStack">
     7                 <interceptor-ref name="defaultStack"></interceptor-ref>
     8                 <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
     9             </interceptor-stack>
    10         </interceptors>
    11         <global-results>
    12             <result name="input">/login.jsp</result>
    13         </global-results>
    14         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    15             <result type="redirectAction">showMain</result>
    16         </action>
    17         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    18             直接引入我们自己定义的拦截器栈,里面已经包含了默认的拦截器栈
    19             <interceptor-ref name="myDefaultStack"></interceptor-ref>
    20             <result>/main.jsp</result>
    21         </action>
    22         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    23             直接引入我们自己定义的拦截器栈,里面已经包含了默认的拦截器栈
    24             <interceptor-ref name="myDefaultStack"></interceptor-ref>
    25             <result>/otherpage.jsp</result>
    26         </action>
    27     </package> -->
    28     
    29     <!-- c. b中存在的问题,还需要在每个要用到地方使用拦截器引用。
    30          解决办法:使用覆盖struts-default.xml配置文件中的默认拦截器栈,让我们的这个称为默认的-->
    31     
    32     <package name="p2" extends="struts-default">
    33         <interceptors>
    34             <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
    35             <interceptor-stack name="myDefaultStack">
    36                 <interceptor-ref name="defaultStack"></interceptor-ref>
    37                 <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    38             </interceptor-stack>
    39         </interceptors>
    40         覆盖了struts-default.xml中定义的默认拦截器栈。由myDefaultStack把defaultStack给替换了
    41         <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
    42         <global-results>
    43             <result name="input">/login.jsp</result>
    44         </global-results>
    45         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    46             <result type="redirectAction">showMain</result>
    47         </action>
    48         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    49             <result>/main.jsp</result>
    50         </action>
    51         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    52             <result>/otherpage.jsp</result>
    53         </action>
    54     </package> 
    struts.xml

                         cb中的问题:还要再每个动作方法中引入拦截器。能不能不写呢?

                                思路:我们在设置【开发模式】时,覆盖掉了一个default.properties中的常量,能不能把struts-default.xml中的默认拦截器栈的设置给覆盖掉呢?答案是可以的。

              解决办法:

                        

     1     <!-- c. b中存在的问题,还需要在每个要用到地方使用拦截器引用。
     2          解决办法:使用覆盖struts-default.xml配置文件中的默认拦截器栈,让我们的这个称为默认的 -->
     3     
     4     
     5     <package name="p2" extends="struts-default">
     6         <interceptors>
     7             <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
     8             <interceptor-stack name="myDefaultStack">
     9                 <interceptor-ref name="defaultStack"></interceptor-ref>
    10                 <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
    11             </interceptor-stack>
    12         </interceptors>
    13         覆盖了struts-default.xml中定义的默认拦截器栈。由myDefaultStack把defaultStack给替换了
    14         <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
    15         <global-results>
    16             <result name="input">/login.jsp</result>
    17         </global-results>
    18         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    19             <result type="redirectAction">showMain</result>
    20         </action>
    21         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    22             <result>/main.jsp</result>
    23         </action>
    24         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    25             <result>/otherpage.jsp</result>
    26         </action>
    27     </package>
    struts.xml

                         dc中出现的问题:当使用了默认拦截器栈,这时候三个动作login,showIndex和show1Action都将被检查登录的拦截器拦截。

                                解决办法:

                                              需要通过AbstractInterceptor类的子类入手,通过查看发现,该类还有一个子类是抽象的:

                                      

                                              所以我们在自定义拦截器时,还可以继承MethodFilterInterceptor并且重写doIntercept方法。

     1 package com.itheima.web.interceptor;
     2 
     3 import javax.servlet.http.HttpSession;
     4 
     5 import org.apache.struts2.ServletActionContext;
     6 
     7 import com.opensymphony.xwork2.ActionInvocation;
     8 import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
     9 /**
    10  * 检查登录的拦截器,最终版本
    11  * @author zhy
    12  *
    13  */
    14 public class CheckLoginInterceptor1 extends MethodFilterInterceptor {
    15 
    16     public String doIntercept(ActionInvocation invocation) throws Exception {
    17         //1.获取HttpSession
    18         HttpSession session = ServletActionContext.getRequest().getSession();
    19         //2.获取session域中的登录标记
    20         Object obj = session.getAttribute("user");
    21         //3.判断是否有登录标记
    22         if(obj == null){
    23             //用户没有登录
    24             return "input";
    25         }
    26         //4.用户登录了,放行
    27         String rtValue = invocation.invoke();
    28         return rtValue;
    29     }
    30 
    31 }
    MyInterceptor 2

                                       并且在struts的配置文件中,配置需要拦截哪些方法,和需要放过哪些方法。

             

        <!-- d. c中存在的问题,当我们配置了默认的拦截器栈时,连登陆都被拦截了。
            解决办法: 在AbstractInterceptor的子类中,还有一个抽象类MethodFilterInterceptor,它里面提供了两个属性。
                    excludeMethods:哪些方法不需要拦截
                    includeMethods:哪些方法需要拦截 -->
         
        <package name="p2" extends="struts-default">
            <interceptors>
                <interceptor name="checkLoginInterceptor1" class="com.itheima.web.interceptor.CheckLoginInterceptor1" />
                <interceptor-stack name="myDefaultStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="checkLoginInterceptor1">
                        给自定义拦截器注入参数,告知他哪些方法不需要拦截
                        <param name="excludeMethods">login</param>
                    </interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
            <global-results>
                <result name="input">/login.jsp</result>
            </global-results>
            <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
                <result type="redirectAction">showMain</result>
            </action>
            <action name="showMain" class="com.itheima.web.action.Demo2Action" >
                <result>/main.jsp</result>
            </action>
            <action name="showOther" class="com.itheima.web.action.Demo2Action" >
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

                                ed中遗留的问题:我们在声明时配置了哪些方法需要拦截,哪些方法不需要拦截。但是在没有写动作类和动作方法之前,不确定方法名叫什么。

                                       解决办法:我们需要在使用拦截器的时候给它注入参数。

                               

     1 <!-- e. d中的问题,我们在声明拦截器和定义拦截器栈的时候,可能根本不知道哪些方法需要拦截,哪些不需要
     2         解决办法:在使用拦截器的时候,注入参数,告诉拦截器哪些需要拦截,哪些不需要
     3      -->
     4     <package name="p2" extends="struts-default">
     5         <interceptors>
     6             <interceptor name="checkLoginInterceptor1" class="com.itheima.web.interceptor.CheckLoginInterceptor1" />
     7             <interceptor-stack name="myDefaultStack">
     8                 <interceptor-ref name="defaultStack"></interceptor-ref>
     9                 <interceptor-ref name="checkLoginInterceptor1"></interceptor-ref>
    10             </interceptor-stack>
    11         </interceptors>
    12         <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
    13         <global-results>
    14             <result name="input">/login.jsp</result>
    15         </global-results>
    16         
    17         <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
    18             <interceptor-ref name="myDefaultStack">
    19                 <!-- 在引用自定义拦截器栈的时候,给指定的拦截器注入参数。方式就是:拦截器名称.属性名称 -->
    20                 <param name="checkLoginInterceptor1.excludeMethods">login</param>
    21             </interceptor-ref>
    22             <result type="redirectAction">showMain</result>
    23         </action>
    24         <action name="showMain" class="com.itheima.web.action.Demo2Action" >
    25             <result>/main.jsp</result>
    26         </action>        
    27         <action name="showOther" class="com.itheima.web.action.Demo2Action" >
    28             <result>/otherpage.jsp</result>
    29         </action>
    30     </package>
    struts.xml

               4.3、拦截器类视图(全):

                                         

    lanjieqi

  • 相关阅读:
    loadrunner(预测系统行为和性能的负载测试工具)
    SOA(面向服务的架构)
    Acunetix Web Vulnerability Scanner(WVS)(Acunetix网络漏洞扫描器)
    Redis主从复制
    Redis启动方式
    Struts2.5以上版本There is no Action mapped for namespace [/] and action name [userAction_login] associated with context path []
    使用Slf4j集成Log4j2构建项目日志系统的完美解决方案
    Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
    intellij 编译 springmvc+hibernate+spring+maven 找不到hbm.xml映射文件
    MySQL8连接数据库
  • 原文地址:https://www.cnblogs.com/soficircle/p/7062117.html
Copyright © 2011-2022 走看看