监听器
1、监听器简介
Web监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件,当Web应用启动时启动,当Web应用销毁时销毁。用于监听域对象的属性发生修改的事件,可以再事件发生前、发生后做一些必要的处理。
Web监听器的用途:
1)统计在线人数和在线用户
2)系统启动时加载初始化信息
3)统计网站访问量
4)跟Spring结合
2、监听器的实现及启动顺序
实现Web监听器步骤:
1)创建一个实现监听器接口的类,实现ServletContextListener接口
package com.oracle.listener;
public class FirstListener implements ServletContextListener{
//初始化方法
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听器启动。。。");
}
//销毁方法
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器销毁。。。");
}
}
2)配置web.xml进行注册
com.oracle.listener.FirstListener
3)启动和停止服务器
监听器启动顺序
在一个web.xml中配置了多个监听器时,启动顺序根据注册的顺序依次启动
在一个web.xml中同时配置了过滤器、监听器和Servlet时,加载的先后顺序为:
3、监听器的分类
按监听器的对象划分
1)用于监听应用程序环境对象(ServletContext)的事件监听器
2)用于监听用户会话对象(HttpSession)的事件监听器
3)用于监听请求消息对象(ServletRequest)的事件监听器
按监听的事件划分
1)监听域对象自身的创建和销毁的事件监听器
监听ServletContext对象的监听器接口ServletContextListener
contextInitialized方法,ServletContext创建时调用
contextDestroyed方法,ServletContext销毁时调用
主要用途:定时器、全局属性对象
监听HttpSession对象的监听器接口HttpSessionListener
sessionCreated方法,session创建时调用
sessionDestroyed方法,session销毁时调用
主要用途:统计在线人数、记录访问日志
监听ServletRequest对象的监听器接口ServletRequestListener
requestInitialized方法,request创建时调用
requestDestroyed方法,request销毁时调用
主要用途:读取参数,记录访问历史
2)监听域对象中的属性的增加和删除的事件监听器
ServletContext对象的监听器接口ServletContextAttributeListener
HttpSession对象的监听器接口HttpSessionAttributeListener
ServletRequest对象的监听器接口ServletRequestAttributeListener
监听器中的方法:
增加属性监听方法attributeAdded
删除属性监听方法attributeRemoved
修改属性监听方法attributeReplaced
3)监听绑定到HttpSession域中的某个对象的状态的事件监听器
Session钝化机制
把服务器中不经常使用的Session对象暂时序列化到系统文件或数据库系统中,当需要时再反序列化到内存中,整个过程由服务器自动完成。Session绑定和钝化、活化操作不需要在web.xml中注册。
Session钝化机制由SessionManager管理。
HttpSessionBindingListener接口
绑定:valueBound方法
解除绑定:valueUnbound方法
HttpSessionActivationListener接口
钝化:sessionWillPassivate方法,对象序列化
活化:sessionDidActivate方法,对象反序列化
序列化:Serializable
Session绑定案例
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 void sessionWillPassivate(HttpSessionEvent httpsessionevent) {
System.out.println("sessionWillPassivate "+httpsessionevent.getSource());
}
//活化
public void sessionDidActivate(HttpSessionEvent httpsessionevent) {
System.out.println("sessionDidActivate "+httpsessionevent.getSource());
}
}
4、Servlet3.0下监听器的使用
使用Servlet3.0的前提条件
使用Servlet3.0新标准jar包;
JDK必须在1.6以上版本;
编译器的编译级别为6.0;
在web.xml文件中,使用3.0规范;
使用支持Servlet3.0特性的web容器,比如Tomcat7;
Servlet3.0下监听器的用法
@WebListener常用的属性
项目案例
统计在线人数
User.java
public class User {
private String sessionIdString;
private String ipString;
private String firstTimeString;
public String getSessionIdString() {
return sessionIdString;
}
public void setSessionIdString(String sessionIdString) {
this.sessionIdString = sessionIdString;
}
public String getIpString() {
return ipString;
}
public void setIpString(String ipString) {
this.ipString = ipString;
}
public String getFirstTimeString() {
return firstTimeString;
}
public void setFirstTimeString(String firstTimeString) {
this.firstTimeString = firstTimeString;
}
}
SessionUtil.java
public class SessionUtil {
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;
}
}
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;//在线用户List
userList = (ArrayList<User>)arg0.getSession().getServletContext().getAttribute("userList");
if(SessionUtil.getUserBySessionId(userList, arg0.getSession().getId())!=null){
userList.remove(SessionUtil.getUserBySessionId(userList, arg0.getSession().getId()));
}
}
}
MyServletRequestListener.java
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
private ArrayList<User> userList;//在线用户List
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
userList = (ArrayList<User>)arg0.getServletContext().getAttribute("userList");
if(userList==null)
userList = new ArrayList<User>();
HttpServletRequest request = (HttpServletRequest) arg0.getServletRequest();
String sessionIdString = request.getSession().getId();
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);
}
}