JSP三大組件之監聽器和過濾器

監聽器(Listener)

**理解:**監聽器就是對項目起到監聽的作用,它能感知到包括request(請求域),session(會話域)和applicaiton(應用程序)的初始化和屬性的變化;

web監聽器是Servlet中一種特殊的類,能監聽web中的特定時間,比如ServletContext,HttpSession,ServletRequest的創建和銷燬;變量的創建、銷燬和修改等。可以在某些動作前後增加處理,實現監控。

監聽器就是一個實現特定接口的普通Java程序,這個程序專門用於監聽一個Java對象的方法調用或屬性改變,當被監聽對象發生上述事件後,監聽器某個方法將立即被執行。

1、 監聽器接口和註冊

​ 監聽器接口主要在 javax.servlet 和 javax.servlet.http 的包中。對應上文的三類,有以下這些接口:

​ 第一類:

名稱 作用
javax.servlet.ServletContextListener 它能響應Servlet生命週期事件,它提供了ServletContext創建之後和ServletContext關閉之前的會被調用的方法。
javax.servlet.http.HttpSessionListener 它能響應HttpSession的創建、超時和失效事件。
javax.servlet.http.HttpActivationListener 它在一個HttpSession激活或者失效時被調用。
javax.servlet.ServletRequestListener 它能響應一個ServletRequest的創建或刪除。

​ 第二類:

名稱 作用
javax.servlet.ServletContextAttributeListener 它能響應ServletContext範圍內的屬性添加、刪除、替換事件。
javax.servlet.http.HttpSessionAttributeListener 它能響應HttpSession範圍內的屬性添加、刪除、替換事件。
javax.servlet.http.HttpSessionBindingListener 可以實現這個接口來保存HttpSession範圍的屬性。當有屬性從HttpSession添加或者刪除時,它能做出響應。
javax.servlet.ServletRequestListener 它能響應ServletRequest範圍的屬性添加、刪除、修改事件。

2、Listener部署

編寫一個監聽器,只需要寫一個Java類來實現對應的監聽器接口就可以了。在Servlet 3.0和Servlet 3.1中提供了兩種註冊監聽器的方法。一種是使用WebListener註解。例如:

@WebListener
public class ListenerClass implements ListenerInterface {
}

​ 第二種是在部署描述文檔中增加一個listener元素。

<listener>
    <listener-class>fully-qualified listener class</listener-class>
</listener>

3、listener實際應用

  • 統計在線人數,利用HttpSessionLisener
  • 加載初始化信息:利用ServletContextListener
  • 統計網站訪問量、實現訪問監控等

獲取當前在線人數

package com.mycompany.mvc.listener;  
  
import javax.servlet.http.HttpSessionEvent;  
import javax.servlet.http.HttpSessionListener;  
  
public class myHttpSessionListener implements HttpSessionListener{  
  
    public static int peopleOnLine = 0;  
      
    @Override  
    public void sessionCreated(HttpSessionEvent hse) {  
        System.out.println("myHttpSessionListener.sessionCreated():"+hse);  
        peopleOnLine++;  
        hse.getSession().setAttribute("peopleOnLine",peopleOnLine);  
    }  
  
    @Override  
    public void sessionDestroyed(HttpSessionEvent hse) {  
        System.out.println("myHttpSessionListener.sessionDestroyed():"+hse);  
        peopleOnLine--;  
        hse.getSession().setAttribute("peopleOnLine",peopleOnLine);  
    }  
} 
<%=session.getAttribute("peopleOnLine")%>  

過濾器(Filters)

過濾器是Servlet的高級特性之一,也別把它想得那麼高深,只不過是實現Filter接口的Java類罷了!

當瀏覽器發送請求給服務器的時候,先執行過濾器,然後才訪問Web的資源。服務器響應Response,從Web資源抵達瀏覽器之前,也會途徑過濾器。。

過濾器可以比喻成一張濾網。我們想想現實中的濾網可以做什麼:在泡茶的時候,過濾掉茶葉。那濾網是怎麼過濾茶葉的呢?規定大小的網孔,只要網孔比茶葉小,就可以實現過濾了!

引申在Web容器中,過濾器可以做:過濾一些敏感的字符串【規定不能出現敏感字符串】、避免中文亂碼【規定Web資源都使用UTF-8編碼】、權限驗證【規定只有帶Session或Cookie的瀏覽器,才能訪問web資源】等等等,過濾器的作用非常大,只要發揮想象就可以有意想不到的效果

過濾器其實也是責任鏈模式的一種實現,FilterChain層層往下執行,直到最後沒有過濾器,就到了「目標資源」

**理解:**就是對請求起到過濾的作用,它在監聽器之後,作用在servlet之前,對請求進行過濾;

1、Filter API

Filter的實現必須繼承 javax.servlet.Filter 接口。這個接口包含了 Filter 的三個生命週期:init,doFilter,destroy。

Servlet容器初始化 Filter 時,會觸發 Filter 的 init 方法,一般在應用開始時,而不是在相關資源使用時才初始化,這個方法只調用一次。init 定義如下:

void init(FilterConfig filterConfig)

​ 當Servlet 容器每次處理Filter相關資源時,都會調用該Filter實例的doFilter方法。doFilter包含三個參數,定義如下:

void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

​ 在doFilter中可以訪問ServletRequest、ServletResponse。

​ 在Filter的doFilter的實現中,最後一行需要調用FilterChain 中的 doFilter 方法。注意Filter的doFilter方法裏的第三個參數,就是filterChain的實例:

filterChain.doFilter(request, response)

2、Filter部署

第一種方式:在web.xml文件中配置

<filter>
    //用於爲過濾器指定一個名字,該元素的內容不能爲空。
    <filter-name>FilterDemo1</filter-name>
	//元素用於指定過濾器的完整的限定類名。
    <filter-class>FilterDemo1</filter-class>
</filter>

//<filter-mapping>元素用於設置一個Filter 所負責攔截的資源
<filter-mapping>
    //用於設置filter的註冊名稱。該值必須是在元素中聲明過的過濾器的名字
    <filter-name>FilterDemo1</filter-name>
    //設置 filter 所攔截的請求路徑(過濾器關聯的URL樣式)
    <url-pattern>/*</url-pattern>
</filter-mapping>

第二種方式:通過註解配置

@WebFilter(urlPatterns = {"*.jsp","*.do"})

2.1 Filter的配置詳解

  • 具體的資源路徑
/index.jsp

只有訪問index.jsp的時候,過濾器纔會被執行
  • 攔截目錄
/user/*

訪問/user目錄下的所有資源的時候,過濾器纔會被執行
  • 後綴名攔截
*.jsp

訪問所有jsp頁面都會被攔截
  • 攔截所有資源
/*

3、Filter實際應用

一般用於完成通用的操作。如:登錄驗證、統一編碼處理、敏感字符過濾……

編碼過濾器(解決亂碼的問題)

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-----filterEncoding dofillter----");
         //將request和response強轉成http協議的
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;


        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=UTF-8");
        // 放行,轉到下一個過濾器
        filterChain.doFilter(request, response);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章