一. 简介
定义:
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>