设为首页 收藏本站
查看: 923|回复: 0

[经验分享] Apache Shiro学习笔记(七)Servlet3.0 Listener介绍

[复制链接]

尚未签到

发表于 2018-11-19 12:10:47 | 显示全部楼层 |阅读模式
鲁春利的工作笔记,好记性不如烂笔头
  

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

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

  1、实现Listener接口

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

  •   1.1 Servlet Context Events
->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方式


     
     com.invicme.apps.shiro.listener.XXXListener
  说明:

  在线人数统计网上一般的实现方式是实现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");
        }
    }
}  





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-636990-1-1.html 上篇帖子: LAMP_apache安装_2 下篇帖子: Apache外网验证访问 内网直接通过
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表