监听器

一. 简介

定义:
1. servlet规范中定义的一种特殊类
2. 用于监听ServletContext , HttpSession , 和ServletRequest等域对象的创建与销毁事件
3. 用于监听域对象的属性发生修改的事件
4. 在事件发生之前、发生后做一些必要的处理。

应用:
统计在线人数;系统初始化时加载初始化信息;统计网站访问量

二. 分类

按监听的事件可分为以下三种:

1.监听域对象自身的创建和销毁的事件监听器

1)ServletContent–实现ServletContextListener接口
可以用于做定时器,可以通过获取web.xml中的<content param>初始化参数来加载全局属性对象

2)HttpSession–实现HttpSessionListener接口
可以用于统计在线人数和记录访问日志

3)ServletRequest–实现ServletRequestListener接口
可以用于读取request里的参数,记录访问历史

2.监听域对象中的属性的增加和删除的事件监听器

1)ServletContent–实现ServletContextAttributeListner接口
2)HttpSession–实现HttpSessionAttributeListner接口
3)ServletRequest–实现ServletRequestAttributeListner接口

其内部有attributeAdded(),attributeRemoved()和attributeReplaced()方法,可通过传进来的参数对增添,删除或修改的属性进行操作

3.监听绑定到HttpSession域中的某个对象的状态的事件监听器

HttpSession 中对象的状态包括 绑定-解除绑定,钝化-活化
1..绑定-解除绑定
实际上就是通过setAttribute()和removeAttribute()方法将属性在session中存储或移除
对该状态监听要实现的是HttpSessionBindingListener接口,分别对应valueBound()方法和valueUnbound()方法
2..钝化-活化
正常情况下,session是存在于服务器的内存中的,但是如果出现很多用户同时在线的情况,服务器内存的开销将是巨大的,会直接影响服务器的性能,session的钝化机制可以有效的解决这个问题:web服务器将不经常使用的session对象序列化到存储设备中,当使用到的时候再将其进行恢复,反序列化到内存当中,整个过程由服务器自动完成
对该状态监听要实现的是HttpSessionActavationListener和Serializable接口,两种状态分别对应sessionWillPassivate()方法和sessionDidActivate()方法

注意:
- 使用以上两种监听器应该是在javabean的类中实现相应的接口,而不是直接创建监听器
- 以上两种监听器不需要在web.xml中注册

三. 统计在线用户和人数

需求:统计在线用户人数,及在线用户的ip
分析:统计在线人数可以通过session对象的创建进行统计,获取用户ip可以通过request对象获取

1..MyHttpSessionListener.java –监听Session对象的创建及销毁

package lisener;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import entity.User;

public class MyHttpSessionListener implements HttpSessionListener {
    private int usernumber = 0;
    public void sessionCreated(HttpSessionEvent se) {
        usernumber++;
        se.getSession().getServletContext().setAttribute("usernumber", usernumber);
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        usernumber--;
        se.getSession().getServletContext().setAttribute("usernumber", usernumber);
        //该会话结束,需将该用户从用户列表中删除 
        ArrayList<User> userlist = (ArrayList<User>)se.getSession().getServletContext().getAttribute("userlist");
        String sessionId = null;
        if((sessionId = se.getSession().getId())!=null)
        {
            for (User user : userlist) {
                if(user.getSessionId().equals(sessionId)){  //该用户存在于用户列表中
                    userlist.remove(user);
                }
            }
        }
    }
}

2..MyServletRequestListener.java – 获取request对象中存储的信息

package lisener;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.SimpleFormatter;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;

import entity.User;

public class MyServletRequestListener implements ServletRequestListener{

    private ArrayList<User> userlist;  //创建在线用户列表
    public void requestDestroyed(ServletRequestEvent sre) {

    }

    public void requestInitialized(ServletRequestEvent sre) {
        userlist = (ArrayList<User>)sre.getServletContext().getAttribute("userlist");
        if(userlist==null)
            userlist = new ArrayList<User>();

        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
        String sessionId = request.getSession().getId();

        for (User user : userlist) {
            if(user.getSessionId().equals(sessionId)){  //该用户存在于用户列表中
                return;
            }
        }
        //新建用户,初始化信息,存到用户列表中
        User user = new User();
        user.setSessionId(sessionId);
        user.setIp(request.getRemoteAddr());
        user.setLoadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userlist.add(user);

        sre.getServletContext().setAttribute("userlist", userlist);
    }
}

3..User.java –用户实体类

package entity;

public class User {
    private String sessionId;
    private String ip;
    private String loadtime;
    setter,getter方法。。。。
}

4..index.jsp–表示层
(需导入User类)

<body>
           当前在线用户人数:<%=request.getSession().getServletContext().getAttribute("usernumber") %><br/>
    <%
    ArrayList<User> userlist = (ArrayList<User>)request.getSession().getServletContext().getAttribute("userlist");
    if(userlist!=null){
        for (User user : userlist) {        
    %>
    ip:<%=user.getIp() %><br>
    loadtime:<%=user.getLoadtime() %><br>
    <% 
        }
    }
    %>
  </body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值