Struts2內建攔截器
Strus2框架內建了大量的攔截器完成了框架幾乎70%的工作,比如,params攔截器將HTTP請求中的參數解析出來,設置成Action的屬性;servlet-config攔截器直接將HTTP請求中的HttpServletRequest實例和HttpServletResponse實例傳給Action;fileUpload攔截器負責解析請求參數中的文件域,並將一個文件域設置成Action的3個屬性...
由於默認的struts攔截器棧中定義了許多框架的常用操作,且若Action中使用了自定義攔截器,struts-default包中定義的defaultStack將不起作用,從而無法完成HTTP參數映射到Action各屬性的過程,因此大部分情況下,爲某個Action指定了相應的攔截器後,組合使用多個攔截器/攔截器棧,或者自定義一個攔截器棧,其中包含對defaultStack的引用。
3.攔截器的實現原理
定義接口
public interface Dog { public void info(); public void run();
定義接口實現類
public class DogImpl implements Dog{ public void info() { ... } public void run(){ ... } }
系統攔截器類
public class DogIntercepter { public void method1(){} public void method2(){} }
上面只是些普通的JAVA類,實現攔截器功能關鍵是下面的代理類
public class ProxyHandler implemtsInvocationHandler { private Objecttarget;//需被代理的目標對象 //創建攔截器實例 DogIntercepter di = newDogIntercepter(); //執行代理的目標方法時,該Invoke方法會被自動調用 public Object invoke(Object proxy, Methodmethod, Object[] args) { Objectresult = null; if(method.getName().equals("info"){ di.methord1(); result =method.invoke(tart,args); di.method2(); } else { result =methos.invoke(target,args); } return result; } public void setTarget(Objecto){ this.target=o; } }
代理工廠類
public class MYProxyFactory{ public static Object getProxy(Objectobject){ ProxyHandler handler = newProxyHandler(); handler.setTarget(object); return Proxy.newProxyInstance(Dogimpl.class.getClassLoader(),object.getClass().getInterfaces(),handler); } }
主程序
public class Test{ public static void main(String[]args){ Dog targetObject = newDogImpl(); Dog dog = null; //以目標對象創建代理 Object proxy =MyProxyFactory.getProxy(targetObject); if(proxy instance of Dog) { dog=(Dog)proxy; } dog.info(); dog.run(); } }
上例通過JDK動態代理,在執行目標方法之前調用攔截器方法一,在執行目標方法之後調用攔截器方法二。
4. 攔截器及攔截器棧的配置
在Struts.xml中配置攔截器
<interceptor name="name"class="class"/>
還可以指定攔截器參數
<interceptor name="name"class="class">
<param name="param name">…</param>
</interceptor>
在Struts.xml中配置攔截器棧
攔截器棧是由多個攔截器組成的,即一個攔截器棧包含了多個攔截器。
<interceptor-stack name="stackname">
<interceptor-ref name="interceptor 1"/>
<interceptor-ref name="interceptor 2"/>
<interceptor-ref name="interceptor stack 1"/>
</interceptor>
提示:一個包中所有的攔截器都應定義在<interceptors…/>元素中
5. 攔截器及攔截器棧的使用
通過<interceptor-ref…/>元素來使用攔截器和攔截器棧。下面是在Action中定義攔截器的配置示例:
<action name="..." ...> ...... <!-- interceptor 1--> <interceptor-refname="int1"/> <!--interceptor 2 --> <interceptor-refname="int2"> <param name="...">...</param> </nterceptor-ref> </action>
7.使用自定義攔截器
實現攔截器類
如果用戶要開發自己的攔截器類,有如下兩種方式:
實現com.opensymphony.xwork2.interceptor.Interceptor接口
繼承AbstractInterceptor類
Interceptor定義如下:
public interface Interceptor extendsSerializable {
/**
* Called to let an interceptor clean up any resources it has allocated.
*/
void destroy();
/**
* Called after an interceptor is created, but before any requests areprocessed using
* {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept}, giving
* the Interceptor a chance to initialize any needed resources.
*/
void init();
/**
* Allows the Interceptor to do some processing on the request beforeand/or after the rest of the processing of the
* request by the {@link ActionInvocation} or to short-circuit theprocessing and just return a String return code.
*
* @param invocation the action invocation
* @return the return code, either returned from {@linkActionInvocation#invoke()}, or from the interceptor itself.
* @throws Exception any system-level error, as defined in {@linkcom.opensymphony.xwork2.Action#execute()}.
*/
String intercept(ActionInvocation invocation) throws Exception;
}
我們的攔截器必須重寫Interceptor接口中的intercept方法,該方法有一個ActionInvocation的參數,該參數實例可以用於獲得被攔截的Action實例。
MyAction action =(MyAction)invocation.getAction();
一旦獲得了Action實例,幾乎獲得了Action的全部控制權:
可以實現將HTTP請求參數解析出來,設置成Action的屬性(這是系統攔截器乾的事情)
可以直接將HTTP請求中的HttpServletRequest實例和HttpServletResponse實例傳給Action(這是servlet-config攔截器乾的事情)
…..
下面是個自定義攔截器類的例子
攔截器類
importcom.jj.test.redirect.RedirectTest;
importcom.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyInterceptor extendsAbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation) throws Exception {
RedirectTest action = (RedirectTest)invocation.getAction();
System.out.println(action.getTarget());
System.out.println("Start------");
long start = System.currentTimeMillis();
//執行Action的exceute方法
String result = invocation.invoke();
long end = System.currentTimeMillis();
System.out.println("End------"+(end-start));
return result;
}
}
ActionInvocation 類常用方法
getAction方法 -獲取Action實例
getInvocationContext方法 - 獲取ActionContext實例
invoke方法 - 執行該攔截器的後一個攔截器,或者直接執行Action的execute方法
在intercept方法中獲取Session
ActionContext ctx =invocation.getInvocationContext();
Map session = ctx.getSession();
struts.xml中的配置
<package name="redir"namespace="/redir" extends="struts-default"> <interceptors> <interceptor name="MyInterceptor"class="com.jj.test.interceptor.MyInterceptor"></interceptor> </interceptors> <default-interceptor-refname="MyInterceptor"/> <action name="RedirTest"class="com.jj.test.redirect.RedirectTest"> <result name="SUCCESS"type="dispatcher">/${target}.jsp</result> </action> </package>