本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/44310967
A:监听器的定义
专门用于其他对象身上发生的事件或状态改变进行监听和相应事件处理的对象,
当被监听的对象发生改变时,立即采取相应的行动。
客户端请求 ServletContext --> Application 上下文对象 由容器创建
web监听器 Httpsession--> Session 保存上下文信息的机制 保存每个会话
服务器端操作 ServletHttpRequest--> Request 客户发送请求时创建
监听器是servlet规范中定义的一种特殊类;
用于监听ServletContext、httpsession和ServletRequest等域对象的创建和销毁事件;
用于监听域对象的属性发生修改的事件;
可以再事件发生前、发生后做一些必要的处理。
B:web监听器的主要用途:
1. 统计在线人数和在线用户
2. 系统启动时加载初始化信息
3. 统计网站访问量
4. 跟Spring结合
C:一个web监听器实例
步骤:
1. 创建一个实现监听器接口的类
2. 配置web.xml文件进行注册
监听器启动顺序:
多个监听器启动顺序按照注册顺序执行的
优先级:监听器 >过滤器>servlet
D:监听器分类
按照监听的对象划分
1. 用于监听应用程序对象 (ServletContext)的事件监听器
2. 用于监听用户会话对象(HttpSession)的事件监听器
3. 用于监听请求消息对象(ServletRequest)的事件监听器
按照监听的事件划分
1.监听域对象自身的创建和销毁的事件监听器
ServletContext --> ServletContextListener
主要用途:定时器 全局属性对象
HttpSession --> HttpSessionListener
主要用途:统计在线人数 记录访问日志
Session销毁:关闭服务器 ; Session超时 ; 关闭浏览器,Session过期
在web.xml中配置session过期时间
ServletReqest ServletRequestListener
主要用途:读取参数 记录访问历史
2.监听域对象中的属性的增加和删除的事件监听器
ServletContext --> servletContextAttributeListener 上下文
HttpSession--> HttpSessionAttributeListner 一次会话
HttpServletRequest --> ServletRequestAtttibuteListener 一次请求
request.getAttribute() 放在域对象中的参数
request.getParameter() request的请求参数 www.baidu.com/username=zs
需要将username放到Attribute中,request.setAttribute("username","zs");
放在域对象中的属性 直接通过EL表达式就可取出 <%=username%>。
在多次点击按钮请求时, 由于request在访问结束后就销毁了,在request域中不存有上一次获取的参数,就会add;
session和context在容器中都存有,就会直接replace。
3.监听绑定到HttpSession域中的某个对象的状态的事件监听器
绑定-->解除绑定
绑定:保存-setAttribute
解除绑定:移除-removeAttribute
钝化-->活化
钝化:将Session对象持久化到存储设备上
活化:将session对象将一个存储设备上恢复
钝化原因:session放在服务器中的,当在线对象特别多,session内存开销很大,session的钝化机制就可解决;
将服务器中暂时不使用的session对象 序列化到系统文件或数据库中;
在需要使用时反序列化到系统内存中 整个过程由服务器自动完成。
Tomcat两种Session钝化管理器:
<a>Session钝化机制由SessionManager管理
org.apache.catalina.session.StandardManager
当Tomcat服务器被关闭或重启时 tomcat服务器会将当前内存中的Session对象钝化到服务器文件系统中;
另一种情况是web应用程序被重新加载时 内存中的Session对象也会被钝化到服务器的文件系统中;
钝化后的文件被保存:Tomcat安装路径
/work/Catalina/hostname/applicationname/SESSION.ser
<b>org.apache.catalina.session.Persistentmanager
在钝化基础上进行扩张,
可以配置主流内存的Session对象数目,将不常使用的Session对象保存到文件系统或数据库,当使用时再重新加载
默认情况下 tomcat提供两个钝化驱动类:
org.apache.Catalina.FileStore 和 org.apache.Catalina.JDBCStore
HttpSessionBindingListener类
绑定:valueBound方法
解除绑定:valueUnbound方法
HttpSessionActivationListener类
钝化:sessionWillPassivate方法
活化:sessionDidActivate方法
不需要在web.xml中注册;
钝化和活化必须实现序列化serializable接口才行。
E:监听器的实例--在线人数统计
import java.util.ArrayList;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import com.my.entity.User;
import com.my.util.SessionUtil;
/**
* 计数监听器
*/
@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()));
}
}
}
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import com.my.entity.User;
import com.my.util.SessionUtil;
@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);
}
}
import java.util.ArrayList;
import com.my.entity.User;
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;
}
}
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;
}
}
F:servlet3.0下的使用:只需要增加注解即可
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener("This is My Servlet 3.0 Listener")
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("contextDestroyed");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("contextInitialized");
}
}