1.监听器的定义
- Servlet规范中定义的一种特殊类
- 用于监听ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件
- 用于监听域对象的属性发生修改的事件
- 可以在事件发生前、发生后做一些必要的处理
2.第一个实例讲解
2.1 Web监听器的用途
- 统计在线人数和在线用户
- 系统启动时加载初始化信息
- 统计网站访问量
- 跟Spring结合
2.2 创建一个监听器的步骤
- 创建一个实现监听器接口的类
- 配置web.xml进行注册
2.3 监听器的启动顺序
3.监听器的分类
3.1 按照监听的对象划分
3.2 按照监听的事件划分
3.2.1监听对象自身的创建和销毁的事件监听器
3.2.1.1 ServletContextListener
FirstListener .java
public class FirstListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
//tomcat服务关闭时执行
String initParam = arg0.getServletContext().getInitParameter("initParam");
System.out.println("contextDestroyed执行了。。。。:initParam ="+initParam);
}
public void contextInitialized(ServletContextEvent arg0) {
//tomcat服务开启时执行
System.out.println("contextInitialized执行了。。。。");
}
}
web.xml
<context-param>
<param-name>initParam</param-name>
<param-value>imooc</param-value>
</context-param>
<listener>
<listener-class>com.imooc.listener.FirstListener</listener-class>
</listener>
3.2.1.2 HttpSessionListener
3.2.1.3 ServletRequestListener
3.2.2监听域对象中的属性的增加和删除的事件监听器
3.2.3监听绑定到HttpSession域中的某个对象的状态的事件监听器
4.Servlet3.0下监听器的使用
5.实际项目中常用案例
用监听器实现在线用户人数的统计,并且输出一些用户的信息。
MyHttpSessionListener.java(计算人数)
@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);
ArrayList<User> userList = null;
userList = (ArrayList<User>) arg0.getSession().getServletContext()
.getAttribute("userList");
//如果这个用户存在不,就把这个session所对应的user从userList中移除
if (SessionUtil.getUserBySessionId(userList, arg0.getSession().getId()) != null) {
userList.remove(SessionUtil.getUserBySessionId(userList, arg0
.getSession().getId()));
arg0.getSession().setAttribute("userList", userList);
}
}
}
MyServletRequestListener .java(获取用户信息)
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
private ArrayList<User> userList;
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
//arg0.getServletContext().setAttribute("userList", userList);
userList = (ArrayList<User>) arg0.getServletContext().getAttribute(
"userList");
if (userList == null || userList.size() == 0) {
userList = new ArrayList<User>();
}
HttpServletRequest request = (HttpServletRequest) arg0
.getServletRequest();
String sessionIdString = request.getSession().getId();
//如果这个session所对应的用户没有在userList中,就这个用户加入userList中
if (SessionUtil.getUserBySessionId(userList, sessionIdString) == null) {
User user = new User();
user.setSessionIdString(sessionIdString);
user.setFirstTimeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date()));
user.setIpString(request.getRemoteAddr());
userList.add(user);
}
arg0.getServletContext().setAttribute("userList", userList);
}
}
SessionUtil.java(判断这个登录的用户是否是已经登陆的用户)
public class SessionUtil {
//输入一个userList(用户的集合)和sessionID,遍历userList,查看是否有与这个sessionId匹配的用户,有的话,将这个用户返回
public static Object getUserBySessionId(ArrayList<User> userList,String sessionIdString) {
for (int i = 0; i < userList.size(); i++) {
User user = userList.get(i);
if (user.getSessionIdString().equals(sessionIdString)) {
return user;
}
}
return null;
}
}
index.jsp(显示用户信息)
<body>
<h1>当前用户在线人数</h1>
当前用户在线人数:${userNumber}<br/>
<%
//把userList中的所有用户的信息输出来
// ArrayList<User> userList = (ArrayList<User>)request.getSession().getAttribute("userList");?????????
ArrayList<com.imooc.entity.User> userList = (ArrayList<com.imooc.entity.User>)request.getServletContext().getAttribute("userList");
// System.out.println("number============" + userList.size());
if(userList!=null && userList.size() > 0){
for(int i=0;i<userList.size();i++){
User user = userList.get(i);
%>
IP:<%=user.getIpString() %>,<br>
FirstTime:<%=user.getFirstTimeString() %>,<br>
SessionId:<%=user.getSessionIdString() %><br>
<%
}
}
%>
</body>
有待解决的问题:
1. 为啥用户只增不减?
打开两个浏览器,用户数变为2;然后再关闭一个浏览器,说明销毁了一个session,再刷新另外一个浏览器,数量应该变回1才对,可是,结果还是2???
2. 在首页获取用户信息为什么不能用request.getSession().getAttribute,而必须用request.getServletContext().getAttribute???
3. 出现在线人数为空的情况?