美文网首页基础与框架
Listener总结(2)---域对象属性改变监听器

Listener总结(2)---域对象属性改变监听器

作者: 鬼畜的猪 | 来源:发表于2017-04-04 21:51 被阅读110次

    原创文章,转载请注明出处

    之前总结的第一类 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.png

    ​与 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 请求时控制台的输出:

    一次完整的 Request 请求.png

    ​由于在调用 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) {
            
        }
    }
    

    相关文章

      网友评论

        本文标题:Listener总结(2)---域对象属性改变监听器

        本文链接:https://www.haomeiwen.com/subject/kybzottx.html