J2EE監聽器和過濾器基礎

Servlet程序由Servlet,Filter和Listener組成,其中監聽器用來監聽Servlet容器上下文。java

監聽器一般分三類:基於Servlet上下文的ServletContex監聽,基於會話的HttpSession監聽和基於請求的ServletRequest監聽。web

 

  • ServletContex監聽器
ServletContex又叫application,存在範圍是整個Servlet容器生命週期,當系統啓動時就會建立,系統關閉時會銷燬,該對象一般存放一些很是通用的數據,可是不推薦存放太多,不然長期佔據內存空間會影響服務器性能。
基於ServletContex的監聽器能夠繼承兩個接口並實現接口中相應的方法:
ServletContextListener接口定義了兩個方法contextInitialized和contextDestroyed,分別在ServletContex建立和銷燬時觸發;
ServletContextAttributeListener接口定義了三個方法attributeAdded,attributeRemoved和attributeReplaced,分別在給ServletContex添加屬性值,刪除屬性值和替換屬性值時觸發。
下面建立了一個基於Application的監聽器:
/** 
 * Application監聽器,Servlet中的Application即ServletContext 
 * @author Administrator 
 */  
public class ApplicationListener implements ServletContextListener,  
        ServletContextAttributeListener {  
      
    /** 
     * application銷燬時觸發的事件 
     */  
    @Override  
    public void contextDestroyed(ServletContextEvent arg0) {  
        System.out.println("Application銷燬:"+arg0.getServletContext());  
    }  
      
    /** 
     * application初始化時觸發的方法 
     */  
    @Override  
    public void contextInitialized(ServletContextEvent arg0) {  
        System.out.println("Application建立:"+arg0.getServletContext());  
    }  
      
    /** 
     * application中添加屬性值時觸發的方法 
     */  
    @Override  
    public void attributeAdded(ServletContextAttributeEvent arg0) {  
        System.out.println("Application添加新屬性:key="+arg0.getName()+"  value="+arg0.getValue());  
    }  
      
    /** 
     * application中刪除屬性值時觸發的方法 
     */  
    @Override  
    public void attributeRemoved(ServletContextAttributeEvent arg0) {  
        System.out.println("Application移除屬性:key="+arg0.getName()+"  value="+arg0.getValue());  
    }  
      
    /** 
     * application中替換屬性值時觸發的方法 
     */  
    @Override  
    public void attributeReplaced(ServletContextAttributeEvent arg0) {  
        System.out.println("Application替換屬性:key="+arg0.getName()+"  value="+arg0.getValue());  
    }  
  
}  

最後在web.xml須要註冊監聽器,註冊方式很是簡單,注意標籤<description>和<display-name>不是必須的:瀏覽器

<listener>  
    <description>application listener</description>  
    <display-name>application_listener</display-name>  
    <listener-class>com.bless.listener.application.ApplicationListener</listener-class>  
</listener>  

隨後啓動java web項目,監聽器就會運行。服務器

  • Session監聽器
Session對於作web項目的人來講應該很是熟悉了,Session的生命週期是一個用戶的一次會話,簡單的說當一個用戶進入某個網站,在該網站服務器就已經爲用戶建立了一個Session對象,用戶在網站內的任何操做都是在session週期內。
誤區:某些人認爲我進入某網站,隨後關閉瀏覽器,個人session就已經銷燬了。其實否則,由於session存儲在服務器端,服務器並不能主動捕獲到瀏覽器關閉的事件,即便關閉瀏覽器,Session對象依然存在服務器中。因此若是編寫web應用時必定要考慮session何時銷燬,銷燬session對象的方式有兩種:一種是調用session的invalidate方法,另外一種是在web.xml中定義session失效時間session-timeout。
Session監聽器也有兩個接口,其功能與前面介紹的ServletContex相似:HttpSessionListener用於監聽Session建立和銷燬的事件,HttpSessionAttributeListener用於監聽Session屬性賦值,刪除和替換的事件:
/** 
 * Session監聽器 
 * @author Administrator 
 */  
public class SessionListener implements HttpSessionListener,  HttpSessionAttributeListener {  
    
    Vector<HttpSession> listSession = null;  
      
    /** 
     * 建立Session調用的方法 
     * 將session對象放入listSession集合中 
     */  
    public void sessionCreated(HttpSessionEvent arg0) {  
        synchronized (this) {  
            if(listSession == null){  
                listSession = new Vector<HttpSession>();  
            }  
        }  
        listSession.add(arg0.getSession());  
        System.out.println("\n\n建立一個Session:"+arg0.getSession());  
        System.out.println("[當前存在的Session:]");  
        for (HttpSession session : listSession) {  
            System.out.println("--->"+session);  
        }  
    }  
      
    /** 
     * 銷燬Session調用的方法 
     * 移除listSession集合對應session值 
     */  
    public void sessionDestroyed(HttpSessionEvent arg0) {  
        listSession.remove(arg0.getSession());  
        System.out.println("\n\n銷燬一個Session:"+arg0.getSession());  
        System.out.println("[當前存在的Session:]");  
        for (HttpSession session : listSession) {  
            System.out.println("--->"+session);  
        }  
    }  
      
    /** 
     * session屬性添加時調用的方法 
     */  
    public void attributeAdded(HttpSessionBindingEvent arg0) {  
        System.out.println("\n\n添加一條Session-->key:"+arg0.getName()+"    屬性value:"+arg0.getValue());  
    }  

    /** 
     * session屬性替代時調用的方法 
     */   
    public void attributeReplaced(HttpSessionBindingEvent arg0) {  
        System.out.println("\n\n覆蓋一條Session-->key:"+arg0.getName()+"    屬性value:"+arg0.getValue());  
    }  
      
    /** 
     * session屬性移除時調用的方法 
     */  
    public void attributeRemoved(HttpSessionBindingEvent arg0) {  
        System.out.println("\n\n刪除一條Session-->key:"+arg0.getName()+"    屬性value:"+arg0.getValue());  
    }  
}  

在web.xml中定義相應監聽器配置:session

<listener>  
    <listener-class>com.bless.listener.session.SessionListener</listener-class>  
  </listener>  
<!-- Session超時配置 -->  
  <session-config>  
    <session-timeout>1</session-timeout>  
  </session-config>  
  • Request監聽器
request監聽器使用方法跟前面也是很是相似的,一個request生命週期是向服務器發送請求到服務器響應最後反應到頁面的整個過程。Request監聽器對應ServletRequestListener,ServletRequestAttributeListener接口,根據不一樣需求實現相應接口就好了。
/** 
 * Request事件監聽器 
 * @author Administrator 
 */  
public class RequestListener implements ServletRequestListener,  
        ServletRequestAttributeListener {  
  
    @Override  
    public void requestDestroyed(ServletRequestEvent arg0) {  
        System.out.println("request銷燬:"+arg0.getServletRequest());  
    }  
  
    @Override  
    public void requestInitialized(ServletRequestEvent arg0) {  
        System.out.println("request建立:"+arg0.getServletRequest());  
    }  
  
    @Override  
    public void attributeAdded(ServletRequestAttributeEvent arg0) {  
        System.out.println("request屬性添加   key="+arg0.getName()+"   value="+arg0.getValue());  
    }  
  
    @Override  
    public void attributeRemoved(ServletRequestAttributeEvent arg0) {  
        System.out.println("request屬性刪除   key="+arg0.getName()+"   value="+arg0.getValue());  
    }  
  
    @Override  
    public void attributeReplaced(ServletRequestAttributeEvent arg0) {  
        System.out.println("request屬性替換   key="+arg0.getName()+"   value="+arg0.getValue());  
    }  
  
}  

web.xml配置:app

<listener>  
    <listener-class>com.bless.listener.request.RequestListener</listener-class>  
</listener>  
  • Filter過濾器
當頁面發送請求時,符合filter過濾範圍的請求會首先進入過濾器,過濾器就能夠執行一些過濾操做:好比編碼格式,session驗證,日誌記錄等。而這些功能都是本身編寫過濾器實現的。
要實現一個過濾器,須要繼承Filter接口,實現init、doFilter和destroy方法,這三個方法分別在過濾器初始化、過濾器運行和過濾器銷燬時執行。
下面這段代碼,是一個字符集過濾器,每次請求都會設置字符集編碼格式,注意每次請求都會運行doFilter方法,過濾以後你須要在方法內調用FilterChain.doFilter這樣就能讓請求訪問指定的servlet。
假設你不但願請求訪問下一個servlet,你能夠選擇重定向,跳轉到指定頁面。
/** 
 *  
 * @author     : bless<505629625@qq.com> 
 * Create Time : 2011-5-10下午10:38:19 
 * Description : 字符集格式過濾器 
 * 
 */  
public class EncodingFilter implements Filter {  
    //默認編碼格式UTF-8  
    private static final String DEFAULT_ENCODE = "UTF-8";  
      
    private String encodeName; // 編碼格式  
  
    public void destroy() {  
  
    }  
  
    /** 
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 
     */  
    public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  
        try {  
            if (encodeName == null || "".equals(encodeName.trim())) {  
                request.setCharacterEncoding(DEFAULT_ENCODE);  
                response.setCharacterEncoding(DEFAULT_ENCODE);  
            } else {  
                request.setCharacterEncoding(encodeName);  
            }  
        } catch (UnsupportedEncodingException e) {  
            throw new UnsupportedEncodingException("編碼格式過濾錯誤,請確認web.xml填入了正確的編碼格式");  
        }  
        chain.doFilter(request, response);  
    }  
  
    /** 
     * @see Filter#init(FilterConfig) 
     */  
    public void init(FilterConfig fConfig) throws ServletException {  
        //獲取web.xml配置的<param-name>encodeName</param-name>的值  
        this.setEncodeName(fConfig.getInitParameter("encodeName"));   
    }  
  
    public String getEncodeName() {  
        return encodeName;  
    }  
  
    public void setEncodeName(String encodeName) {  
        this.encodeName = encodeName;  
    }  
  
}  

而後在web.xml中定義filter便可,標籤init-param能夠作一個參數配置,在filter中經過init方法參數FilterConfig.getInitParameter得到:less

<filter>  
    <filter-name>encoding</filter-name>  
    <filter-class>com.mt.filter.EncodingFilter</filter-class>  
    <init-param>  
        <param-name>encodeName</param-name>  
        <param-value>GBK</param-value>  
    </init-param>  
  </filter>  
  <filter-mapping>  
    <filter-name>encoding</filter-name>  
    <url-pattern>/*</url-pattern>  
  </filter-mapping>  

 

 

轉自:http://blessht.iteye.com/blog/1164492ssh

http://www.iteye.com/topic/483158ide

http://chinaxxren.iteye.com/blog/811604性能

 http://blog.csdn.net/fyxxq/article/details/9731747

 http://ooft.iteye.com/blog/551498

 http://www.iteye.com/topic/82565

相關文章
相關標籤/搜索