web的监听器,你需要知道这些...

一、简介

Listener是Servlet规范的另一个高级特性,它用于监听java web程序的事件,例如创建、修改、删除session,request,context等,并触发相应的处理事件,这个处理事件是由web容器回掉的。

学过安卓开发的同学一定很熟悉view.setonClickLister();这样的对安卓控件的监听。java web也是这样的 ,根据不同的listner 和不同的event,可以完成相应的处理事件。

二、Listerner的分类

Listerner分为八种,前三种是用于监听对象的创建和销毁,中间三种用于监听对象属性的变化,后两种用于监听Session内对象。

  • httpSessionListner: 监听session的创建与销毁,用于收集在线用户信息。
  • servletContextListener:监听context的创建与销毁,context代表当前web应用,该listener可用于启动时获取web.xml的初始化参数。
  • servletRequestListener: 监听request 的创建与销毁。
  • httpSessionAttributeListener 监听session的种属性变化
  • ServletContextAttributeListener
  • ServletRequestAttributeListener
  • HttpSessionBindingListener,监听对象存入或者移除 session
  • httpSessionActivationListener,钝化和重新加载 session的监听

三、监听session、request、servletContext

直接上代码,下面监听了这三个对象创建销毁。

public class ListenerTest implements HttpSessionListener ,ServletContextListener,ServletRequestListener{

    Log log=LogFactory.getLog(getClass());
    public void requestDestroyed(ServletRequestEvent sre) {
        HttpServletRequest request=(HttpServletRequest) sre.getServletRequest();
        long time=System.currentTimeMillis()-(Long)request.getAttribute("time");
        log.info("请求处理时间"+time);

    }

    public void requestInitialized(ServletRequestEvent sre) {
        HttpServletRequest request=(HttpServletRequest) sre.getServletRequest();
        String uri=request.getRequestURI();
        uri=request.getQueryString()==null?uri:(uri+"?"+request.getQueryString());
        log.info("ip"+request.getRemoteAddr()+uri);
        request.setAttribute("time", System.currentTimeMillis());

    }

    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext servletContext=sce.getServletContext();
        log.info("关闭:"+servletContext.getContextPath());

    }

    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext=sce.getServletContext();
        log.info("启动:"+servletContext.getContextPath());

    }

    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session=se.getSession();
        log.info("创建:session:"+session.getId());

    }

    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session=se.getSession();
        log.info("销毁建:session:"+session.getId());

    }

}

需要在web.xml中配置:

 <listener>
    <listener-class>com.forezp.listener.ListenerTest</listener-class>
 </listener>

四、监听对象属性的变化

  • httpSessionAttributeListener 监听session的种属性变化
  • ServletContextAttributeListener
  • ServletRequestAttributeListener

以上三种方法用于监听session ,context,request的属性发生变化,例如添加、更新、移除。 下面以session的属性变化为例子:

public class SessionAttributeListener  implements HttpSessionAttributeListener{

    Log log=LogFactory.getLog(getClass());
    public void attributeAdded(HttpSessionBindingEvent se) {
        HttpSession httpSession=se.getSession();
        log.info("新建属性:"+se.getName()+"值:"+se.getValue());

    }

    public void attributeRemoved(HttpSessionBindingEvent se) {
        HttpSession httpSession=se.getSession();
        log.info(" 删除属性:"+se.getName()+"值:"+se.getValue());

    }

    public void attributeReplaced(HttpSessionBindingEvent se) {
        HttpSession httpSession=se.getSession();
        log.info(" 修改属性:"+se.getName()+"原来的值:"+se.getValue()+"新值:"+httpSession.getAttribute(se.getName()));

    }

}

web.xml配置,此处省略。

五、监听session内的对象

  • HttpSessionBindingListener,当对象被放到session里执行valueBond();当对象被移除,执行valueUnbond();
  • httpSessionActivationListener,服务器关闭,会将session的内容保存在硬盘里,这个过程叫钝化;服务器重启,会将session的内容从硬盘中重新加载。钝化时执行sesionWillPassivate(),重新加载sessionDidActivate();

举个例子:

public class User implements HttpSessionBindingListener,HttpSessionActivationListener,Serializable {

    private String username;
    private String password;

    public void valueBound(HttpSessionBindingEvent httpsessionbindingevent) {
        System.out.println("valueBound Name:"+httpsessionbindingevent.getName());
    }

    public void valueUnbound(HttpSessionBindingEvent httpsessionbindingevent) {
        System.out.println("valueUnbound Name:"+httpsessionbindingevent.getName());
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    //钝化
    public void sessionWillPassivate(HttpSessionEvent httpsessionevent) {
        System.out.println("sessionWillPassivate "+httpsessionevent.getSource());
    }
    //活化
    public void sessionDidActivate(HttpSessionEvent httpsessionevent) {
        System.out.println("sessionDidActivate "+httpsessionevent.getSource());
    }

}

init.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
request.getSession().setAttribute("currentUser", new com.forezp.entity.User());

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'init.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    这是初始化值的界面
    <button onclick="location.href='<%=request.getContextPath()%>/init.jsp';">Init</button>
    <button onclick="location.href='<%=request.getContextPath()%>/destory.jsp';">Destory</button>
  </body>
</html>

destroy.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

request.getSession().removeAttribute("currentUser");
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'destory.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    这是销毁界面
    <button onclick="location.href='<%=request.getContextPath()%>/init.jsp';">Init</button>
    <button onclick="location.href='<%=request.getContextPath()%>/destory.jsp';">Destory</button>
  </body>
</html>

当访问init.jsp,再访问destroy.jsp;再访问init,jsp,再关闭服务器,重启;log日志如下:

valueBound Name:currentUser valueUnbound Name:currentUser sessionWillPassivate org.apache.catalina.session.StandardSessionFacade@33f3be1 sessionDidActivate org.apache.catalina.session.StandardSessionFacade@33f3be1

六、显示在线人数:

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    private int userNumber = 0;

    @Override
    public void sessionCreated(HttpSessionEvent arg0) {
        userNumber++;
        arg0.getSession().getServletContext().setAttribute("userNumber", userNumber);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {
        userNumber--;
arg0.getSession().getServletContext().setAttribute("userNumber", userNumber);

    }

}

jsp中显示:

<body>
    当前在线用户人数:${userNumber }<br/>
</body>

这是一个简答的统计在线人数的方法,如果你需要知道这些人来自哪里,需要配合httpRequestListener配合,也可以实现单登陆,在这里不写代码了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习网

常见的 Java 错误及避免方法之第五集(每集10个错误后续持续发布)

当输入期间意外终止文件或流时,将抛出“EOFException”。 以下是抛出EOFException异常的一个示例,来自JavaBeat应用程序:

623
来自专栏zhisheng

Spring Boot 2.0(七):SpringApplication 深入探索

对于第一个注解 @SpringBootApplication,我已经在博客 Spring Boot 2.0系列文章(六):Spring Boot 2.0中Spr...

831
来自专栏开发技术

spring事务源码解析

  在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内...

541
来自专栏Java Edge

@Autowired注解实现原理

5028
来自专栏林欣哲

Spring Boot 知识点速记

本文是学习2小时学会Spring Boot和Spring Boot进阶之Web进阶的SpringBoot常用知识点速记。 SpringBoot前置知识: Spr...

3177
来自专栏java 成神之路

Spring mvc ContextLoaderListener 原理解析

1865
来自专栏精讲JAVA

接口方法上的注解无法被 @Aspect 声明的切面拦截的原因分析

在Spring中使用MyBatis的Mapper接口自动生成时,用一个自定义的注解标记在Mapper接口的方法中,再利用@Aspect定义一个切面,拦截这个注解...

1462
来自专栏Java技术栈

Spring Boot 2.x 启动全过程源码分析(上)入口类剖析

Spring Boot 的应用教程我们已经分享过很多了,今天来通过源码来分析下它的启动过程,探究下 Spring Boot 为什么这么简便的奥秘。

840
来自专栏Java后端生活

JavaWeb(十六)Listener监听器

监听器:专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。

1294
来自专栏编码小白

ofbiz view渲染处理机制

1.1.1.1  初始化        ControlServlet.java 这是一个servlet,其配置文件在web.xml里 <servle...

2986

扫码关注云+社区