Struts2 中的攔截器和 servelt 中的過濾器是非常的相似的。如果學過過濾器的話,肯定能夠感覺的到,儘管有些微的不同。可是struts2的攔截器到底如何使用呢,爲什麼會有這些配置呢? 接下來一一來看。
過濾器和攔截器是非常相似的,過濾器 public interface Filter 接口裏面有三個方法:
- init(FilterConfig filterConfig),
- destroy(),
- doFilter(ServletRequest request, ServletResponse response, FilterChain chain),
這裏面的 doFilter() 方法是最重要的,在 struts2 中 String intercept(ActionInvocation invocation)就相當於此方法。
如何完成一個攔截器呢?在 struts2 中要實現一個接口 這個接口是什麼呢?在哪呢?,是否在哪聽說過?是 webwork 是我們以前聽的最多的關於攔截器的框架, struts2 用了其中一個核心的東西,這個東西在是什麼呢?是 xwork 。恩,有了它纔可以攔截,好了我們在哪找呢?在 com.opensymphony.xwork2.interceptor 中找,裏面有個 Interceptor 這是個接口,裏面也有三個方法,有 init, destroy 和 intercept 三個方法,而在 struts2
裏面的所有的攔截器都繼承這個接口!
struts2接受客戶端請求時,在執行action之前已經執行了自身默認的攔截器,這些攔截器完成struts2的大部分初始化的功能,比如設置屬性值等。
執行完這些攔截器後,再執行action,返回客戶端時,還得經過攔截器的攔截,最終返回客戶端。下面我們開始模擬攔截器的實現過程:
1、新建自己的攔截器:
- package com.beckham.interceptors;
- /**
- * @author Owner
- * Jan 14, 2010 2:36:14 PM
- * 定義一個接口
- */
- public interface MyInterceptor {
- public void inteceptor(Invocation invocation) ;
- }
2、攔截器的具體實現
- package com.beckham.interceptors;
- /**
- * @author Owner
- * Jan 14, 2010 2:41:26 PM
- *
- * spring
- * com.beckham.interceptors
- * FirstInterceptor.java
- */
- public class FirstInterceptor implements MyInterceptor {
- public void inteceptor(Invocation invocation) {
- System.out.println("第一個攔截器開始。。。。");
- //調用invoke方法
- invocation.invoke() ;
- System.out.println("第一個攔截器結束.......");
- }
- }
- package com.beckham.interceptors;
- /**
- * @author Owner
- * Jan 14, 2010 2:42:22 PM
- *
- * spring
- * com.beckham.interceptors
- * SecondInterceptor.java
- */
- public class SecondInterceptor implements MyInterceptor {
- public void inteceptor(Invocation invocation) {
- System.out.println("第二個攔截器開始.....");
- //調用invoke方法
- invocation.invoke() ;
- System.out.println("第二個攔截器結束......");
- }
- }
3、需要執行的action
- package com.beckham.interceptors;
- /**
- * @author Owner
- * Jan 14, 2010 2:45:30 PM
- *
- * spring
- * com.beckham.interceptors
- * Action.java
- */
- public class Action {
- public String execute() {
- System.out.println("執行execute方法");
- return null ;
- }
- }
4、控制器,該控制器調配執行攔截器和action
- package com.beckham.interceptors;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * @author Owner
- * Jan 14, 2010 2:46:44 PM
- *
- * spring
- * com.beckham.interceptors
- * Invocation.java
- */
- public class Invocation {
- List<MyInterceptor> interceptors = new ArrayList<MyInterceptor>();
- int index = -1;
- public Invocation() {
- //需要執行的攔截器
- this.interceptors.add(new FirstInterceptor());
- this.interceptors.add(new SecondInterceptor());
- }
- public void invoke() {
- index++;
- if (index < interceptors.size()) {
- //一次調用攔截器的inteceptor方法
- interceptors.get(index).inteceptor(this);
- } else {
- //攔截器攔截完畢後執行action
- new Action().execute();
- }
- }
- }
5、main方法執行,在struts2框架中,前臺的一個請求被過濾器攔截後就執行攔截,然後再執行action
- package com.beckham.interceptors;
- /**
- * @author Owner
- * Jan 14, 2010 2:47:32 PM
- *
- * spring
- * com.beckham.interceptors
- * Test.java
- */
- public class Test {
- public static void main(String[] args) {
- //struts2的攔截器入口就是invoke方法
- new Invocation().invoke() ;
- }
- }
模擬結果:
第一個攔截器開始。。。。
第二個攔截器開始.....
執行execute方法
第二個攔截器結束......
第一個攔截器結束.......
從模擬結果分析,攔截器相當於包裹在action外面的屏障,要達到執行action的目的,需要穿過屏障-------->執行action-------->穿出屏障
攔截器的實現其實是aop編程思想,在實現相應邏輯的前後,加上其他邏輯的實現,而且沒有任何依賴關係。