拦截器介绍

来源:互联网 发布:mac vim编辑器 编辑:程序博客网 时间:2024/06/06 12:52

一、拦截器介绍


拦截器是Struts2最重要的组成部分,因为Struts2的大部分操作都是通过他完成的,以下列举了一些内建拦截器:

(1)params :拦截HTTP请求参数,并完成类型转换

(2)fileUpload:文件上传拦截器;

(3)conversionError:处理类型转换错误的拦截器;

(4)exception:处理异常的拦截器,因此在execute方法中,才可以安心抛出异常;

(5)i18n:处理国际化拦截器;

(6)static-params:用于在struts.xml中注入action属性值;

(7)validation:在xml文件中配置的输入校验拦截器;

(8)workflow:处理手动校验的拦截器

以上内建拦截器都在struts2-core-Xxx.jar\struts-default.xml中定义,因此在定义<package>时需要填写 extends="struts-default",这样能够自动继承这些拦截器;

而我们还可以自己定义拦截器,不过注意,如果配置了自定义拦截器,则会让内建拦截器消失,因此我们必须要显式地引用内建拦截器,如下 <interceptor name="defaultStack"/>;

Struts2通过可插拔设计,可以添加、删除任意拦截器,非常灵活;


拦截器&拦截器栈


拦截器栈是由多个拦截器构成的,在使用时可以把他当作一个“大一点的拦截器”,除了定义不同,使用起来是相同的;

拦截器栈应用:多个拦截器同时使用时,方便管理;

拦截器栈

    拦截器1

    拦截器2

    拦截器3

 

拦截器的使用:拦截器配置在<action>中,即为某个Action配置一个或多个拦截器, 即执行Action方法之前会被拦截器拦截,并执行拦截器方法;


二、自定义拦截器

 

1.配置自定义拦截器和拦截器栈

 

定义拦截器或拦截器栈的根元素为<interceptors>,而此元素是<package>的子元素;


(1)定义拦截器:<interceptors>的子元素

<interceptor name="拦截器名" class="实现类"/>

注:如果需要传入参数,则表示拦截器类属性的默认值;

[html] view plaincopy
  1. <interceptor name="拦截器名" class="实现类">  
  2.     <param name="name">value</param>  
  3. </interceptor>  

(2)引用拦截器:<action>或<interceptor-stack>的子元素

如果是<action>的子元素,则表示在action中配置一个拦截器;

<interceptor-ref name="拦截器名"/>

注:如果需要传入参数,则表示使用拦截器时类属性的值,将覆盖定义拦截器时传入的参数;

[html] view plaincopy
  1. <interceptor-ref name="拦截器名">  
  2.     <param name="name">value</param>  
  3. </interceptor-ref>  

(3)定义拦截器栈:<interceptors>的子元素

<interceptor-stack name="拦截器栈名">

    <interceptor-ref name="拦截器名"/>

    <interceptor-ref name="拦截器名"/>

</interceptor-stack>

(4)引用拦截器栈:<action>的子元素

<interceptor-ref name="拦截器栈名"/>

注:这里传递参数方法比较特殊,因为拦截器栈中有多个拦截器,因此必须以如下形式执行参数:

<interceptor-ref name="拦截器栈名">

<param name="interceptorName.attrName">value</param>

</interceptor-ref>

(5)定义默认拦截器:<package>的子元素

<default-interceptor-ref name="拦截器或拦截器栈名"/>

注:可以在此处传入参数:

<default-interceptor-ref name="默认拦截器名">

    <param name="name">value</param>

</default-interceptor-ref>

默认拦截器使用时机:当action中没有显式地引用拦截器,则会使用默认拦截器;

 

2.定义拦截器类

实现Interceptor接口,并实现方法:

(1)public void init();        //初始化,一般为空

(2)public void destroy();        //销毁,一般为空

(3)public String interceptor(ActionInvocation invocation)throws Exception;    //实现拦截功能,返回值为execute方法返回值;

String result = invocation.invoke()即可调用拦截器拦截的Action的execute()方法,并返回逻辑视图;
public String interceptor(ActionInvocation invocation)throws Exception{

        //调用execute()方法之前

        String result = invocation.invoke();

        //调用execute()方法之后

        return result;

注意:

(1)在使用自定义拦截器时,会丢失默认内建拦截器,因此需要显式引用默认拦截器栈:<interceptor-ref name="defaultStack"/>

(2)如果在一个Action中配置了两个拦截器,则如果拦截器A在拦截器B之前引用,即:

<action>

<interceptor-ref name="A"/>

<interceptor-ref name="B"/>

</action>

则虽然在两个拦截器中都调用了invocation.invoke(),但是只会执行一遍Action方法;Action方法执行之前,拦截器A比拦截器B先执行;Action方法执行之后,则拦截器B比拦截器A先执行;

即结果为:

 A拦截器语句

B拦截器语句

execute

B拦截器语句

A拦截器语句


代码实例:


HelloAction.java


[java] view plaincopy
  1. package org.xiazdong.action;  
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;  
  4.   
  5. public class HelloAction extends ActionSupport {  
  6.     public String execute()throws Exception{  
  7.         System.out.println("execute...");  
  8.         return SUCCESS;  
  9.           
  10.     }  
  11. }  


Interceptor01.java


[java] view plaincopy
  1. package org.xiazdong.interceptor;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.Interceptor;  
  5.   
  6. public class Interceptor01 implements Interceptor {  
  7.     private String name;  
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.     @Override  
  15.     public void destroy() {  
  16.     }  
  17.     @Override  
  18.     public void init() {  
  19.     }  
  20.     @Override  
  21.     public String intercept(ActionInvocation invocation) throws Exception {  
  22.         System.out.println("name属性:"+name);  
  23.         System.out.println("execute方法之前...");  
  24.         String result = invocation.invoke();  
  25.         System.out.println("execute方法之后...");  
  26.         return result;  
  27.     }  
  28. }  


struts.xml


[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>  
  6.     <constant name="struts.devMode" value="true" />  
  7.     <package name="default" namespace="/" extends="struts-default">  
  8.         <interceptors>  
  9.             <interceptor name="interceptor01" class="org.xiazdong.interceptor.Interceptor01">  
  10.                 <param name="name">xiazdong</param>  
  11.             </interceptor>  
  12.             <interceptor-stack name="stack">  
  13.                 <interceptor-ref name="defaultStack"></interceptor-ref>  
  14.                 <interceptor-ref name="interceptor01"></interceptor-ref>  
  15.             </interceptor-stack>  
  16.         </interceptors>  
  17.         <action name="hello" class="org.xiazdong.action.HelloAction">  
  18.             <interceptor-ref name="stack"></interceptor-ref>  
  19.             <result>/index.jsp</result>  
  20.         </action>  
  21.     </package>  
  22. </struts>  

3.方法过滤


默认自定义拦截器将会拦截Action的所有方法,比如在Action中定义了login()方法、regist()方法,则默认会拦截两个方法,如果只想拦截login()方法,则需要通过如下步骤实现过滤:

(1)继承 MethodFilterInterceptor类;

(2)重写public String doIntercept(ActionInvocation invocation)throws Exception;此方法和intercept方法功能一致,只是名字不一样;

(3)在struts.xml中配置参数进行过滤:在<interceptor-ref>的子元素中设置:

<param name="excludeMethods">不过滤的方法1,不过滤的方法2</param>、<param name="includeMethods">需要过滤的方法</param>


注意:如果一个方法在includeMethods和excludeMethods参数中同时列出,则还是会被拦截;


代码实例:

如果Action中提供了login()、regist()方法,则struts.xml中如下配置,可以实现login()不被拦截器拦截:

struts.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5.   
  6. <struts>  
  7.   
  8.     <constant name="struts.devMode" value="true" />  
  9.   
  10.     <package name="default" namespace="/" extends="struts-default">  
  11.   
  12.         <interceptors>  
  13.             <interceptor name="interceptor01"  
  14.                 class="org.xiazdong.interceptor.Interceptor01">  
  15.                 <param name="name">xiazdong</param>  
  16.             </interceptor>  
  17.             <interceptor-stack name="stack">  
  18.                 <interceptor-ref name="defaultStack">  
  19.   
  20.                 </interceptor-ref>  
  21.                 <interceptor-ref name="interceptor01">  
  22.                     <param name="excludeMethods">login</param>  
  23.                 </interceptor-ref>  
  24.             </interceptor-stack>  
  25.         </interceptors>  
  26.         <action name="hello" class="org.xiazdong.action.HelloAction">  
  27.             <interceptor-ref name="stack"></interceptor-ref>  
  28.             <result>/index.jsp</result>  
  29.         </action>  
  30.     </package>  
  31. </struts>  


补充:PreResultListener应用


在Action的介绍中也介绍过这个类,是用于在Action方法执行之后、转入物理视图之前被调用;
这个类也可以在拦截器类中被添加,则只要应用该拦截器的action都会起作用,步骤如下:
(1)定义MyPreResultListener:
public class MyPreResultListener implements PreResultListener{
public void beforeResult(ActionInvocation invocation,String resultCode);
}
(2)在intercept方法中添加invocation.addPreResultListener(new MyPreResultListener());
即可;

代码:

MyPreResultListener.java
[java] view plaincopy
  1. package org.xiazdong.interceptor;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.PreResultListener;  
  5.   
  6. public class MyPreResultListener implements PreResultListener {  
  7.   
  8.     @Override  
  9.     public void beforeResult(ActionInvocation arg0, String arg1) {  
  10.         System.out.println("beforeResult...");  
  11.     }  
  12.   
  13. }  

Interceptor01.java

[java] view plaincopy
  1. package org.xiazdong.interceptor;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.Interceptor;  
  5. import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;  
  6.   
  7. public class Interceptor01 extends MethodFilterInterceptor{  
  8.   
  9.     @Override  
  10.     public String doIntercept(ActionInvocation invocation) throws Exception {  
  11.           
  12.         invocation.addPreResultListener(new MyPreResultListener());  
  13.         System.out.println("execute1方法之前...");  
  14.         String result = invocation.invoke();  
  15.         System.out.println("execute1方法之后...");  
  16.         return result;  
  17.     }  
  18. }  

结果如下:

 execute1方法之前...
regist...
beforeResult...
execute1方法之后...

可以看出,此方法在Action方法一执行完就触发PreResultListener,比拦截器先执行;




最后配上一张图作为结尾:






原创粉丝点击