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

    Struts2拦截器是可插拨式的设计:如果需要使用某个拦截器,只需在配置文件中应用该拦截器即可;如果不需要使用,只需在配置文件中取消应用该拦截器。
    Struts2拦截器由struts-default.xml、struts.xml等文件进行配置,所以开发者很容易扩展自己的拦截器。

    1、内建拦截器
    package继承了struts-default包就可使用struts-default.xml中定义的拦截器:

               <!--<interceptor name="拦截器名" class="拦截器实现类"/>-->
              
    <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
                <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
                <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
                <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
                <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
                <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
                <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
                <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
                <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
                <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
                <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
                <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
                <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
                <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
                <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
                <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
                <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
                <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
                <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
                <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
                <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
                <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
                <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
                <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
                <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
                <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
                <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
                <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
                <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
                <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
                <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
                <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
    View Code

    2、拦截器配置和使用
        1)定义
            会在Action的excute方法执行之前被执行
       <!-- 该元素可以出现0至1次-->
              <interceptors>
                  <!-- interceptor元素和interceptor-stack至少出现其中之一,可以都出现-->
     
                  <!-- 该元素可以出现0至多次-->
                  <interceptor name="" class="">
                      <!-- 该元素可以出现0至多次-->
                      <param name="参数名">参数值</param>
                  </interceptor>
     
                <!-- 该元素可以出现0至多次-->
                <interceptor-stack name="">
                    <!-- 下面元素可以出现1到多次 -->
                    <interceptor-ref name="">
                        <!-- 该元素可以出现0至多次-->
                          <param name="参数名">参数值</param>
                    </interceptor-ref>
                </interceptor-stack>
     
              </interceptors>
        2)使用
            <!-- 定义Action,可以出现0到多次 -->
            <action name="" class="" method="" converter="">
                。。。
                <!-- 下面元素可以出现0到多次 -->
                <interceptor-ref name="拦截器名或拦截器栈名">
                    <!-- 该元素可以出现0至多次-->
                      <param name="参数名">动态参数</param>
                </interceptor-ref>
                 。。。
            </action>
     
    3)配置默认拦截器        
           <!-- 该元素可以出现0至1次-->
              <default-interceptor-ref name="拦截器名或拦截器栈名">
                  <!-- 该元素可以出现0至多次-->
                  <param name="参数名">参数值</param>
              </default-interceptor-ref>
     
    3、自定义拦截器
        1)编写实现com.opensymphony.xwork2.interceptor.Inteceptor接口的拦截器类
               
     
     1 public class SimpleInterceptor
     2     extends AbstractInterceptor
     3 {
     4     // 简单拦截器的名字
     5     private String name;
     6     // 为该简单拦截器设置名字的setter方法
     7     public void setName(String name)
     8     {
     9         this.name = name;
    10     }
    11     public String intercept(ActionInvocation invocation)
    12         throws Exception
    13     {
    14         // 取得被拦截的Action实例
    15         LoginAction action = (LoginAction)invocation.getAction();
    16         // 打印执行开始的时间
    17         System.out.println(name + " 拦截器的动作---------" +
    18             "开始执行登录Action的时间为:" + new Date());
    19         // 取得开始执行Action的时间
    20         long start = System.currentTimeMillis();
    21         // 执行该拦截器的后一个拦截器
    22         // 如果该拦截器后没有其他拦截器,则直接执行Action的被拦截方法
    23         String result = invocation.invoke();
    24         // 打印执行结束的时间
    25         System.out.println(name + " 拦截器的动作---------" +
    26             "执行完登录Action的时间为:" + new Date());
    27         long end = System.currentTimeMillis();
    28         System.out.println(name + " 拦截器的动作---------" +
    29             "执行完该Action的时间为" + (end - start) + "毫秒");
    30         return result;
    31     }
    32 }
        2) 在strutx.xml中注册上一步中定义的拦截器。
        3)在Action中引用。
               如果为Action指定了一个拦截器,则系统默认拦截器栈会失去作用,要继续使用则需要显示指定默认拦截器
     
    4、拦截方法的拦截器
     
        1)重写doIntercept()方法
     1 public class MyFilterInterceptor
     2     extends MethodFilterInterceptor
     3 {
     4     // 简单拦截器的名字
     5     private String name;
     6     // 为该简单拦截器设置名字的setter方法
     7     public void setName(String name)
     8     {
     9         this.name = name;
    10     }
    11     // 重写doIntercept()方法,实现对Action的拦截逻辑
    12     public String doIntercept(ActionInvocation invocation)
    13         throws Exception
    14     {
    15         // 取得被拦截的Action实例
    16         LoginAction action = (LoginAction)invocation.getAction();
    17         // 打印执行开始的时间
    18         System.out.println(name + " 拦截器的动作---------"
    19             + "开始执行登录Action的时间为:" + new Date());
    20         // 取得开始执行Action的时间
    21         long start = System.currentTimeMillis();
    22         // 执行该拦截器的后一个拦截器,或者直接指定Action的被拦截方法
    23         String result = invocation.invoke();
    24         // 打印执行结束的时间
    25         System.out.println(name + " 拦截器的动作---------"
    26             + "执行完登录Action的时间为:" + new Date());
    27         long end = System.currentTimeMillis();
    28         // 打印执行该Action所花费的时间
    29         System.out.println(name + " 拦截器的动作---------"
    30             + "执行完该Action的时间为" + (end - start) + "毫秒");
    31         return result;
    32     }
    33 }
     
        2)在配置文件中指定需要被拦截或不需要被拦截的方法
     
        <action name="login" class="org.crazyit.app.action.LoginAction">
           。。。
            <!-- 配置系统的默认拦截器 -->
            <interceptor-ref name="defaultStack"/>
            <!-- 应用自定义的mySimple拦截器 -->
            <interceptor-ref name="mySimple">
                <!-- 重新指定name属性的属性值 -->
                <param name="name">改名后的拦截方法过滤拦截器</param>
                <!-- 指定execute方法不需要被拦截 -->
                <param name="excludeMethods">excludeMethod1,excludeMethod2</param>
                <param name="includeMethods">includeMethod1,includeMethod2</param>
            </interceptor-ref>
        </action>
     
            includeMethods和excludeMethods里有相同方法时,会拦截该方法。
     
        能够指定方法过滤的拦截器有:
                TokenInterceptor、TokenSessionInterceptor、DefaultWorkflowInterceptor、ValidationInterceptor
     
    5、拦截器的执行顺序
        通常认为:先配置,先执行,但也有特殊情况。Action中可以多次使用同一个拦截器,对于excute()方法前的动作,配置在前面的拦截器先起作用,对于在之后的动作,配置在后面的拦截器先起作用。
     
    6、拦截器结果的监听器

        定义拦截结果监听器,需实现PreResultListener接口。

     1 public class MyPreResultListener
     2     implements PreResultListener
     3 {
     4     // 定义在处理Result之前的行为
     5     public void beforeResult(ActionInvocation invocation
     6         ,String resultCode)
     7     {
     8         // 打印出执行结果
     9         System.out.println("返回的逻辑视图为:" + resultCode);
    10 //        try
    11 //        {
    12 //            invocation.invoke();
    13 //        }
    14 //        catch (Exception ex)
    15 //        {
    16 //            ex.printStackTrace();
    17 //        }
    18 //        finally
    19 //        {
    20 //        }
    21     }
    22 }
    View Code
     1 public class BeforeResultInterceptor
     2     extends AbstractInterceptor
     3 {
     4     public String intercept(ActionInvocation invocation)
     5         throws Exception
     6     {
     7         // 将一个拦截结果的监听器注册给该拦截器
     8         invocation.addPreResultListener(new MyPreResultListener());
     9         System.out.println("execute方法执行之前的拦截...");
    10         // 调用下一个拦截器,或者Action的被拦截方法
    11         String result = invocation.invoke();
    12         System.out.println("execute方法执行之后的拦截...");
    13         return result;
    14     }
    15 }
    View Code

       

    执行结果:
        excute方法执行之前的拦截...
        进入excute方法执行体......
        返回的逻辑视图为:success
        excute方法执行之后的拦截...
     
    拦截结果监听器的beforeResult方法可以获得ActionInvocation实例,但是千万不能通过该实例再次调用invoke(),如果调用,会再次进入Action,这样就会进入死循环。

     
    7、覆盖拦截器栈里特定拦截器的参数
               在<interceptor-ref../>的<param../>元素里使用<拦截器名>.<参数名>这种形式指定想要拦截的参数。
                (因为同一个拦截器栈里,不同拦截器可能有相同属性)
     
    8、使用拦截器完成权限控制
    LoginAction类
     1 public class LoginAction extends ActionSupport
     2 {
     3     private String username;
     4     private String password;
     5  
     6     // username的setter和getter方法
     7     public void setUsername(String username)
     8     {
     9         this.username = username;
    10     }
    11     public String getUsername()
    12     {
    13         return this.username;
    14     }
    15  
    16     // password的setter和getter方法
    17     public void setPassword(String password)
    18     {
    19         this.password = password;
    20     }
    21     public String getPassword()
    22     {
    23         return this.password;
    24     }
    25  
    26     public String execute() throws Exception
    27     {
    28         System.out.println("进入execute方法执行体..........");
    29         if (getUsername().equals("crazyit.org")
    30             && getPassword().equals("leegang") )
    31         {
    32             ActionContext ctx = ActionContext.getContext();
    33             Map<String,Object> session = ctx.getSession();
    34             session.put("user" , getUsername());
    35             return SUCCESS;
    36         }
    37         return ERROR;
    38     }
    39 }
    View Code

    AuthorityInterceptor类
    // 权限检查拦截器继承AbstractInterceptor类
    public class AuthorityInterceptor
        extends AbstractInterceptor
    {
        // 拦截Action处理的拦截方法
        public String intercept(ActionInvocation invocation)
            throws Exception
        {
            // 取得请求相关的ActionContext实例
            ActionContext ctx = invocation.getInvocationContext();
            Map session = ctx.getSession();
            // 取出Session里的user属性
            String user = (String)session.get("user");
            //如果没有登录,或者登录所用的用户名不是crazyit.org,都返回重新登录
            if (user != null && user.equals("crazyit.org") )
            {
                return invocation.invoke();
            }
            // 如果没有登录,将服务器提示放入ActionContext中
            ctx.put("tip" ,"您还没有登录,请输入crazyit.org,leegang登录系统");
            // 返回login的逻辑视图
            return Action.LOGIN;
        }
    }
    View Code

    struts.xml
     1 <?xml version="1.0" encoding="GBK"?>
     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.i18n.encoding" value="GBK"/>
     7  
     8     <package name="lee" extends="struts-default">
     9         <!-- 用户拦截器定义在该元素下 -->
    10         <interceptors>
    11             <!-- 定义了一个名为authority的拦截器 -->
    12             <interceptor name="authority" 
    13                 class="org.crazyit.app.interceptor.AuthorityInterceptor"/>
    14         </interceptors>
    15  
    16         <!-- 定义全局Result -->
    17         <global-results>
    18             <!-- 当返回login视图名时,转入loginForm.jsp页面 -->
    19             <result name="login">/WEB-INF/content/loginForm.jsp</result>
    20         </global-results>
    21  
    22         <action name="login" class="org.crazyit.app.action.LoginAction">
    23             <result name="error">/WEB-INF/content//error.jsp</result>
    24             <result>/WEB-INF/content/welcome.jsp</result>
    25         </action>
    26         <!-- 定义一个名为viewBook的Action,其实现类为ActionSupport -->
    27         <action name="viewBook">
    28             <!-- 返回success视图名时,转入viewBook.jsp页面 -->
    29             <result>/WEB-INF/content/viewBook.jsp</result>
    30             <interceptor-ref name="defaultStack"/>
    31             <!-- 应用自定义拦截器 -->
    32             <interceptor-ref name="authority"/>
    33         </action>
    34         <action name="*">
    35             <result>/WEB-INF/content/{1}.jsp</result>
    36         </action>
    37     </package>
    38 </struts>
    View Code

     
     
     
     
     
     
     
  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/goingforward/p/5737115.html
Copyright © 2011-2022 走看看