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

 


 
 
 
 
 
 
 
posted @ 2016-08-04 16:08  JillWen  阅读(190)  评论(0编辑  收藏  举报