官术网_书友最值得收藏!

5.3 Filter技術

雖然Filter技術是Servlet 2.3增加的功能,但是Servlet 3.0也加強了對該技術的支持。Servlet 3.0是Sun公司于2010年發布的,它的開發者包括許多個人和公司團體,充分體現了Sun公司所倡導的代碼開放性原則。由于眾多參與者的共同努力,Servlet 3.0的功能強大了很多,而且性能也有了大幅度提高。

5.3.1 Filter技術原理

Servlet 3.0使得開發人員實現如下目標:

● 簡單性。

● 減輕開發工作量。

● 遵循Web 2.0原則。

為了使開發過程更加輕松,Servlet 3.0引入了注釋。類似于EJB 3.1的改變,注釋的引入使得Web部署描述符web.xml成為可選項。

同時該版本Servlet也支持Filter功能,因為Filter可以使用戶增強request和response對象。Filter雖然不像Servlet一樣,能夠生成request和response對象,但是其能夠在一個request到達Servlet之前預處理request,也可以在離開Servlet時處理response。

一個Filter包括:

● 在Servlet被調用之前截獲。

● 在Servlet被調用之前檢查Servlet的request。

● 根據需要修改request頭和request數據。

● 根據需要修改response頭和response數據。

● 在Servlet被調用之后截獲。

在Filter的最初版本中,一個Filter必須實現javax.servlet.Filter接口并定義3個方法:

● void setFilterConfig(FilterConfig config),設置Filter的配置對象。

● FilterConfig getFilterConfig(),返回Filter的配置對象。

● void doFilter(ServletRequest req, ServletResponse res, FilterChain chain),執行Filter的工作。

服務器每次只調用setFilterConfig方法一次,準備Filter的處理;調用doFilter方法多次,以處理不同的請求。每一個Filter從doFilter()方法中得到當前的request及response。在這個方法中,可以針對request及response進行任何的操作,Filter調用chain.doFilter()方法把控制權交給下一個Filter。一個Filter在doFilter()方法中結束。如果一個Filter想停止request處理而獲得對response的完全控制,那么它可以不調用下一個Filter。

而在Filter的最新版本中,只需要實現javax.servlet.Filter接口并定義兩個方法即可:

● void init(FilterConfig config),進行Filter的初始化工作。

● void doFilter(ServletRequest req, ServletResponse res, FilterChain chain),執行Filter的工作。

5.3.2 Filter示例

一個Filter可以包裝request或response以改變多個方法和提供用戶定制的屬性。Servlet 2.3提供了HttpServletRequestWrapper和HttpServletResponseWrapper來實現,它們能分派最初的request和response,如果要改變一個方法的特性,則必須繼承wapper和重寫方法。下面是一段簡單的日志Filter,用來記錄所有request的持續時間。

      public class LogFilter implements Filter {
          FilterConfig config;
          public void setFilterConfig(FilterConfig config) {
              this.config = config;
          }
          public FilterConfig getFilterConfig() {
              return config;
          }
          public void doFilter(ServletRequest req,
          ServletResponse res,
          FilterChain chain) {
              //獲取環境上下文
              ServletContext context = getFilterConfig().getServletContext();
              //記錄開始時間
              long bef = System.currentTimeMillis();
              //傳遞給下一個Filter或Servlet
              chain.doFilter(req, res);
              //記錄執行完的時間
              long aft = System.currentTimeMillis();
              context.log("Request to " + req.getRequestURI()
              + ": " + (aft-bef));
          }
      }

當服務器端調用setFilterConfig()時,Filter保存config信息,在doFilter()方法中通過config信息得到servletContext。如果要運行這個Filter,則必須配置到web.xml文件中。

          <filter>
          <filter-name> log </filter-name> //定義過濾器的名字
          <filter-class> com.gc.log.LogFilter </filter-class> //定義過濾器類
          </filter>
          <filter-mapping>
          <filter-name>log</filter-name>
          <servlet-name>servletname</servlet-name> //定義要過濾的內容
          </filter-mapping>
          <servlet>
          <servlet-name>servletname</servlet-name> //定義Servlet的名稱
          <servlet-class> com.gc.action.servletclass</servlet-class> //定義Servlet的類
          </servlet>
          <servlet-mapping>
          <servlet-name>servletname</servlet-name>
          <url-pattern>*</url-pattern> //定義要訪問攔截的URL
          </servlet-mapping>

把這個web.xml文件放到WEB-INF下,當每次請求一個request時,先到LogFilter中去并調用doFilter()方法,然后才到各自的Servlet中。

主站蜘蛛池模板: 乐平市| 都兰县| 合作市| 永泰县| 茌平县| 商河县| 宁远县| 婺源县| 新绛县| 衢州市| 北宁市| 壶关县| 白河县| 资中县| 保靖县| 武冈市| 永吉县| 彰武县| 阳江市| 屏南县| 阿勒泰市| 资阳市| 舒兰市| 淮安市| 临洮县| 敦化市| 青河县| 龙井市| 天门市| 库车县| 汪清县| 社旗县| 开远市| 吉木萨尔县| 宜黄县| 莱西市| 金寨县| 天门市| 健康| 边坝县| 东方市|