Listener總結(2)---域對象屬性改變監聽器

​ 之前總結的第一類 Listener,監聽的是 ServletContextHttpSessionServletRequest 這三個對象的創建和銷燬,接下來要介紹的第二類 Listener分別是ServletRequestAttributeListenerServletContextAttributeListenerHttpSessionAttributeListener

​ 從名字不難看出,他們是監聽各自對象中屬性的Listener,每當對象的屬性發生變化(增加、修改或者刪除),相應的監聽器將會收到通知。XXXXXXAttributeListener 中方法的名稱相同,以HttpSessionAttributeListener接口爲例:

package javax.servlet.http;

import java.util.EventListener;
import javax.servlet.http.HttpSessionBindingEvent;

public interface HttpSessionAttributeListener extends EventListener {
    default void attributeAdded(HttpSessionBindingEvent se) {
    }

    default void attributeRemoved(HttpSessionBindingEvent se) {
    }

    default void attributeReplaced(HttpSessionBindingEvent se) {
    }
}

attributeAdded()attributeRemoved()attributeReplaced分別在 Session 中的屬性被添加、移除和改變時被調用,從參數HttpSessionBindingEvent中可以獲得 Session 的詳細信息:

public String login(){
    HttpSession session = ServletActionContext.getRequest().getSession();
    session.setAttribute("UserName", username);
    session.setAttribute("UserName", "defaultUserName");
    session.removeAttribute("UserName");
    return SUCCESS;
}

//自定義MyHttpSessionAttributeListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {

    private Logger logger = Logger.getLogger(MyHttpSessionAttributeListener.class);

    public void attributeAdded(HttpSessionBindingEvent se) {
        logger.debug("attributeAdded: Name: "+ se.getName()+"; Value: "+ se.getValue());
    }

    public void attributeRemoved(HttpSessionBindingEvent se) {
        logger.debug("attributeRemoved: Name: "+ se.getName()+"; Value: "+ se.getValue());
    }

    public void attributeReplaced(HttpSessionBindingEvent se) {
        logger.debug("attributeReplaced: Name: "+ se.getName()+"; Value: "+ se.getValue());
    }
}

​ 在模擬登陸的函數中對 Session 進行一系列操作,可以看到控制檯輸出信息:

​ 與 HttpSessionAttributeListener 的作用類似,ServletContextAttributeListener和ServletContextAttributeListener接口都提供了以上三個方法,用法也大致相同,下面直接給出實現了ServletContextAttributeListener和ServletContextAttributeListener接口的兩個自定義 Listener 類。

MyServletContextAttributeListener.java:

//...
public class MyServletContextAttributeListener implements ServletContextAttributeListener {

    private Logger logger = Logger.getLogger(MyServletContextAttributeListener.class);

    public void attributeReplaced(ServletContextAttributeEvent scae) {
        logger.debug("attributeReplaced: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }

    public void attributeRemoved(ServletContextAttributeEvent scae) {
        logger.debug("attributeRemoved: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }

    public void attributeAdded(ServletContextAttributeEvent scae) {
        logger.debug("attributeAdded: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }
}

MyServletRequestAttributeListener.java:

public class MyServletRequestAttributeListener implements ServletContextAttributeListener {

    private Logger logger = Logger.getLogger(MyServletRequestAttributeListener.class);

    public void attributeReplaced(ServletContextAttributeEvent scae) {
        logger.debug("attributeReplaced: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }

    public void attributeRemoved(ServletContextAttributeEvent scae) {
        logger.debug("attributeRemoved: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }

    public void attributeAdded(ServletContextAttributeEvent scae) {
        logger.debug("attributeAdded: Name: "+ scae.getName()+"; Value: "+ scae.getValue());
    }
}

將之前login函數中的代碼進行修改,使其操作 ServletContext 、Request 和 Session 中的 Attribute,再看控制檯的輸出:

函數 login():

public String login(){
    ServletContext servletContext = ServletActionContext.getServletContext();
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpSession session = request.getSession();
  
    session.setAttribute("UserName", username);
    session.setAttribute("UserName", "defaultUserName");
    session.removeAttribute("UserName");
  
    servletContext.setAttribute("UserName", username);
    servletContext.setAttribute("UserName", "defaultUserName");
    servletContext.removeAttribute("UserName");
  
    request.setAttribute("UserName", username);
    request.setAttribute("UserName", "defaultUserName");
    request.removeAttribute("UserName");
    return SUCCESS;
}

​ 進行一次 Request 請求時控制檯的輸出:

​ 由於在調用 login()方法之前頁面已經進行過一次訪問,第二次訪問時並沒有創建或銷燬 Session,所以這裏只有 RequestListener 進行了響應。
​ 基於上一篇文章的監聽對象創建和銷燬的 Listener,再加上監聽對象屬性的 Listener,實際使用中可以將自定義 Listener 同時繼承兩種接口,將對象的監聽事件放於一處,提高代碼的可維護性:

​ 以 HttpSession 對象的監聽爲例:

//...
public class MyHttpSessionListener implements HttpSessionListener, HttpSessionAttributeListener{

    private static Logger logger = Logger.getLogger(MyHttpSessionListener.class);

    public void sessionCreated(HttpSessionEvent se) {
        logger.debug("sessionCreated");
        logger.debug(se.getSession().getId());
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        logger.debug("sessionDestroyed");
    }

    public void attributeReplaced(HttpSessionBindingEvent se) {
        
    }

    public void attributeRemoved(HttpSessionBindingEvent se) {
        
    }

    public void attributeAdded(HttpSessionBindingEvent se) {
        
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章