• 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

     
     
     
     
     
     
     
  • 相关阅读:
    Linux下chkconfig命令详解
    几种主流的快照技术
    HANA内存数据库与oracle数据库的性能比较
    计算机网络知识汇总
    bzoj1211: [HNOI2004]树的计数 prufer序列裸题
    1003: [ZJOI2006]物流运输 最短路+dp
    HDU
    2243: [SDOI2011]染色 树链剖分+线段树染色
    bzoj1036: [ZJOI2008]树的统计Count 树链剖分
    bzoj1042: [HAOI2008]硬币购物 dp+容斥
  • 原文地址:https://www.cnblogs.com/goingforward/p/5737115.html
Copyright © 2020-2023  润新知