• 欢迎访问VPS岛网站,国外VPS,国内VPS,国外服务器,国内服务器,服务器主机,测评及优惠码,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站 QQ群

Apache Shiro学习笔记(七)Servlet3.0 Listener介绍

Apache技术 luchunli1985 47次浏览 已收录 0个评论

鲁春利的工作笔记,好记性不如烂笔头


当Web应用在Web容器中运行时,Web应用内部会不断地发生各种事件:如Web应用被启动、Web应用被停止、用户session开始、用户session结束等。通常这些Web操作对开发者是透明的,但Servlet API也提供了相应的接口来监控这些变化。

当我们要使用Listener时,只需要两个步骤:
① 定义Listener实现类(实现对应的接口)
② 通过Annotation或在web.xml文件中配置Listener

1、实现Listener接口

不同的Web事件对应的监听器也不同,常用的Web事件监听器接口有如下几个:

->ServletContextListener:用于监听Web应用的启动和关闭
->ServletContextAttributeListener:用于监听ServletContext范围(application)内属性的改变
  • 1.2 Http Session Events

->HttpSessionListener:用于监听用户session的开始和结束
->HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变
->HttpSessionActivationListener:session的passivation是指非活动的session被写入持久设备,activate是反过程。
                 一般情况下和HttpSessionBindingListener一起使用。
->HttpSessionBindingListener:实现HttpSessionBindingListener接口的对象被绑定到session时
                触发valueBound事件,解除绑定时触发valueUnbound事件。
  • 1.3 Servlet Request Events

->ServletRequestListener:用于监听用户请求
->ServletRequestAttributeListener:用于监听ServletRequest范围(request)内属性的改变

一般来说,需要监听哪些Web事件就实现对应接口的方法即可。

2、配置Listener

实现了Listener类之后,还需要配置Listener,可以选择Annotaion方式或web.xml方式。

  • Annotation方式

只需使用@WebListener修饰Listener实现类即可(要求Servlet3.0以上)

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {......}
  • web.xml方式

<listener>
     <!-- 指定Listener的实现类 -->
     <listener-class>com.invicme.apps.shiro.listener.XXXListener</listener-class>
</listener>

说明:

    在线人数统计网上一般的实现方式是实现HttpSessionListener,监控session的创建(create)和销毁(destroy),但在实际的使用过程中,发现destroy并不及时并且在session.invalidate()的时候还会调用一次sessionCreated()。

package com.invicme.apps.shiro.listener;
 
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
 
public class OnlineUserBindingListener implements HttpSessionBindingListener {
    String username;
     
    public OnlineUserBindingListener(String username){
        this.username = username;
    }
    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession session = event.getSession();
        ServletContext application = session.getServletContext();
        // 把用户名放入在线列表
        List onlineUserList = (List) application.getAttribute("onlineUserList");
        // 第一次使用前,需要初始化
        if (onlineUserList == null) {
            onlineUserList = new ArrayList();
            application.setAttribute("onlineUserList", onlineUserList);
        }
        onlineUserList.add(this.username);
    }
 
    public void valueUnbound(HttpSessionBindingEvent event) {
        HttpSession session = event.getSession();
        ServletContext application = session.getServletContext();
 
        // 从在线列表中删除用户名
        List onlineUserList = (List) application.getAttribute("onlineUserList");
        onlineUserList.remove(this.username);
        System.out.println(this.username + "退出。");
    }
}

在LoginController中,每次登录成功之后可以执行一次,session.setAttribute(“loginUserLS”, new OnlineUserBindingListener(username))

3、Listener示例

  • 3.1 Servlet Context Events

package com.invicme.apps.shiro.listener.context;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about ServletContext lifecycle changes.
 */
@WebListener
public class MyServletContextListener implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(MyServletContextListener.class);
    
    public MyServletContextListener() {
        logger.info("MyServletContextListener() was invoke...");
    }

    // Web容器启动的时候执行改方法
    public void contextInitialized(ServletContextEvent sce)  { 
        logger.info("contextInitialized() was invoke.");
    }

    // Web容器reload应用时,首先destroy,然后再initialize
    public void contextDestroyed(ServletContextEvent sce)  { 
        logger.info("contextDestroyed() was invoke.");
    }
    
}


package com.invicme.apps.shiro.listener.context;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about ServletContext attribute changes. 
 */
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    
    private static final Logger logger = Logger.getLogger(MyServletContextAttributeListener.class);
    
    /**
     * Default constructor. 
     */
    public MyServletContextAttributeListener() {
        logger.info("MyServletContextAttributeListener() was invoke..."); 
    }

    // context.setAttribute()
    public void attributeAdded(ServletContextAttributeEvent event)  { 
        logger.info("attributeAdded() was invoke..."); 
    }
    
    // context.setAttribute(已设置过的属性)
    public void attributeReplaced(ServletContextAttributeEvent event)  { 
        logger.info("attributeReplaced() was invoke..."); 
    }
    
    // context.removeAttribute()
    public void attributeRemoved(ServletContextAttributeEvent event)  { 
        logger.info("attributeRemoved() was invoke..."); 
    }
    
}

  • 3.2 Http Session Events

package com.invicme.apps.shiro.listener.session;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about HttpSession lifecycle changes. 
 */
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
    private static final Logger logger = Logger.getLogger(MyHttpSessionListener.class);
    
    /**
     * Default constructor. 
     */
    public MyHttpSessionListener() {
        logger.info("MyHttpSessionListener() was invoke..."); 
    }

    // 会话建立(如:request.getSession())
    public void sessionCreated(HttpSessionEvent se)  { 
        logger.info("sessionCreated() was invoke..."); 
    }

    public void sessionDestroyed(HttpSessionEvent se)  { 
        logger.info("sessionCreated() was invoke..."); 
    }
    
}


package com.invicme.apps.shiro.listener.session;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about HttpSession attribute changes. 
 */
@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    private static final Logger logger = Logger.getLogger(MyHttpSessionAttributeListener.class);
    /**
     * Default constructor. 
     */
    public MyHttpSessionAttributeListener() {
        logger.info("MyHttpSessionAttributeListener() was invoke..."); 
    }

    // session.setAttribute()
    public void attributeAdded(HttpSessionBindingEvent event)  { 
        logger.info("attributeAdded() was invoke..."); 
    }

    // session.setAttribute(已经设置过的属性)
    public void attributeReplaced(HttpSessionBindingEvent event)  { 
        logger.info("attributeReplaced() was invoke..."); 
    }
    
    // session.removeAttribute()
    public void attributeRemoved(HttpSessionBindingEvent event)  { 
        logger.info("attributeRemoved() was invoke..."); 
    }

}


package com.invicme.apps.shiro.listener.session;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Causes an object to be notified when it is bound to or unbound from a session. 
 */
@WebListener
public class MyHttpSessionBindingListener implements HttpSessionBindingListener {
    private static final Logger logger = Logger.getLogger(MyHttpSessionBindingListener.class);
    /**
     * Default constructor. 
     */
    public MyHttpSessionBindingListener() {
        logger.info("MyHttpSessionBindingListener() was invoke..."); 
    }

    public void valueUnbound(HttpSessionBindingEvent event)  { 
        logger.info("valueUnbound() was invoke..."); 
    }

    public void valueBound(HttpSessionBindingEvent event)  { 
        logger.info("valueBound() was invoke..."); 
    }
    
}

  • 3.3 Servlet Request Events

package com.invicme.apps.shiro.listener.request;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about requests coming into and going out of scope of a web application. 
 */
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
    private static final Logger logger = Logger.getLogger(MyServletRequestListener.class);
    /**
     * Default constructor. 
     */
    public MyServletRequestListener() {
        logger.info("MyServletRequestListener() was invoke..."); 
    }

    // 每次Http请求都是一个request,方法调用一次
    public void requestInitialized(ServletRequestEvent sre)  { 
        logger.info("requestInitialized() was invoke..."); 
    }
    
    // 一次request请求执行完毕
    public void requestDestroyed(ServletRequestEvent sre)  { 
        logger.info("requestDestroyed() was invoke..."); 
    }
    
}


package com.invicme.apps.shiro.listener.request;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.Logger;

/**
 * @author lucl
 * Interface for receiving notification events about ServletRequest attribute changes. 
 */
@WebListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
    private static final Logger logger = Logger.getLogger(MyServletRequestAttributeListener.class);
    /**
     * Default constructor. 
     */
    public MyServletRequestAttributeListener() {
        logger.info("MyServletRequestAttributeListener() was invoke..."); 
    }

    public void attributeAdded(ServletRequestAttributeEvent srae)  { 
        logger.info("attributeAdded() was invoke...");
    }

    public void attributeReplaced(ServletRequestAttributeEvent srae)  { 
        logger.info("attributeReplaced() was invoke...");
    }

    public void attributeRemoved(ServletRequestAttributeEvent srae)  { 
        logger.info("attributeRemoved() was invoke...");
    }
    
}

4、Listener监听测试Servlet

package com.invicme.apps.shiro.servlet;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.invicme.apps.shiro.listener.session.MyHttpSessionBindingListener;

/**
 * @author lucl
 */
@WebServlet("/httpServlet")
public class MyHttpServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    private static final Logger logger = Logger.getLogger(MyHttpServlet.class);
       
    public MyHttpServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Servlet Context Attribute Event
        {
            ServletContext servletContext = request.getServletContext();
            // attributeAdded
            logger.info("=============servletContext.setAttribute");
            servletContext.setAttribute("sc_name", "sc_value");
            logger.info("=============servletContext.attributeReplaced");
            servletContext.setAttribute("sc_name", "sc_value");
            logger.info("=============servletContext.removeAttribute");
            servletContext.removeAttribute("sc_name");
        }
        // Session Event
        {
            logger.info("=============request.getSession()=>sessionCreated");
            HttpSession session = request.getSession();
            logger.info("=============session.setAttribute()");
            session.setAttribute("s_name", "s_value");
            logger.info("=============session.attributeReplaced()");
            session.setAttribute("s_name", "s_value");
            logger.info("=============session.removeAttribute()");
            session.removeAttribute("s_name");
            // 实现HttpSessionBindingListener接口的对象被绑 定到session时触发valueBound事件,解除绑定时触发valueUnbound事件。
            MyHttpSessionBindingListener bindingListener = new MyHttpSessionBindingListener();
            logger.info("=============session.setAttribute(\"bind\", bindingListener)");
            session.setAttribute("bind", bindingListener);
            logger.info("=============session.removeAttribute(\"bind\")");
            session.removeAttribute("bind");
            
            logger.info("=============session.invalidate()=>sessionDestroyed");
            session.invalidate();
        }
        
        // Request Event
        {
            logger.info("=============request.setAttribute()");
            request.setAttribute("r_name", "r_value");
            logger.info("=============request.attributeReplaced()");
            request.setAttribute("r_name", "r_value");
            logger.info("=============request.removeAttribute()");
            request.removeAttribute("r_name");
        }
    }

}


VPS岛 的文章和资源来自互联网,仅作为参考资料,如果有侵犯版权的资源请尽快联系站长,我们会在24h内删除有争议的资源。丨 转载请注明Apache Shiro学习笔记(七)Servlet3.0 Listener介绍
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址