Web监听器简介、用途:
Web监听器简介
1.由Servlet规范提供的,可以对客户端的请求、服务端的操作进行监听2.用于监听ServletContext、HttpSession、ServletRequest等域对象的创建于销毁事件,
分别对应application、session、request对象,
3.用于监听域对象的属性发生修改的事件
4.可以在事件发生前、发生后做一些必要的处理
application是上下文对象,是由容器创建和初始化的,范围是整个web应用,而且整个web应用只有一个application对象,当web服务器关闭时,就会被销毁。
session是保存上下文信息的机制,是针对每一个会话的,是放在服务器端通过sessionid来区分的。在浏览器和服务器结束后,都会把session销毁。
request对象是当客户发送请求时,容器就会创建一个ServletRequest对象,来进行封装请求处理,同时会创建一个ServletResponse对象来进行封装响应处理,在访问结束请求之后,这个对象就会被销毁。
Web监听器的用途:
1、统计在线人数和在线用户;2、系统启动时加载初始化信息;
3、统计网站访问量;
4、跟Spring结合;
优先级:
监听器>过滤器>servelt监听器分类:
1.按监听器的对象划分:
a 用户监听应用程序环境对象(ServletContext)的时间监听器b 用于监听用户会话对象(HttpSession)的事件监听器
c 用于监听请求消息对象(ServletRequest)的事件监听器。
2.按事件划分
a 监听域对象自身的创建和销毁的事件监听器b 监听域对象中的属性的增加和删除的事件监听器
c 监听绑定到HttpSession域中的某个对象的状态的事件监听器
ServletContext的创建和销毁:
实现ServletContextListener接口一个项目中可以有多个ServletContextListener,但是只有一个ServletContext对象
主要用途:定时器,全局属性对象
监听器小案例
1.创建类FirstListener 实现ServletContextListener接口
2.配置web.xml--->listeners params
<context-param>
<param-name>initparm</param-name>
<param-value>imooc</param-value>
</context-param>
<listener>
<listener-class>FirstListener</listener-class>
</listener>
3.重写函数contextInitialized()、contextDestroyed()
获取ServletContext对象:ServletContext sc = arg0.getServletContext();
获取初始化参数:String initparm= sc.getInitParameter("initparm");
可以往ServletContext里放一些值进去sc.setAttribute("name", "user");
System.out.println("contextDestroyed"+initparm+sc.getAttribute("name"));
HttpSession的创建和销毁:
实现HttpSessionListener接口一个HttpSession可以注册多个HttpSessionListener接口,
一个web应用中可以有多个HttpSession对象
主要用途:统计在线人数,记录访问日志
<session-config>
<!-- 设定超时销毁时间(分钟) 然而这个时间并不精确,而且当为0的时候表示无超时销毁-->
<session-timeout>1</session-timeout>
</session-config>
ServletRequest的事件监听器:
实现ServletRequestListener接口一个ServletRequest可以注册多个ServletRequestListener接口
主要用途:读取参数,记录访问历史
request监听的是用户的每一个访问请求
获取ServletRequest对象: ServletRequest sr = sre.getServletRequest();
获取初始化参数:sr.getInitParmeter("initparm");
属性的增加和删除的事件监听器
ServletContext、HttpSession、ServletRequest对象的中属性的增加和删除有单独的事件监听器XXAttributeListner
监听的事件包括
attributeAdded()
attributeRemoved()
attributeReplaced()
区别:
request.getAttribute的值获得是从request.setAttribute的值
request.getParameter是请求的参数值
init.jsp
request.setAttribute("name","name");
request.getSession().setAttribute("name","name");
request.getSession().getServletContext().setAttribute("name","name");
destroy.jsp
request.removeAttribute("name");
request.getSession().removeAttribute("name");
request.getSession().getServletContext().removeAttribute("name");
监听绑定到httpsession的某个对象的状态的事件监听器
1,绑定到Session中的 对象有多种状态,分别是 绑定 解除绑定 钝化 活化。绑定 是保存,通过session.setattribute把对象保存到session的对象当中,解除绑定,remove。钝化就是将session持久化存储设备上。活化就是将session对象从一个存储设备上进行恢复。
2,session的钝化机制:
session正常是放到服务器内存当中的,当在线用户很多时,session内存的开销是巨大的,会直接影响web服务器的性能,session的钝化机制就会解决这个问题
session钝化的本质就是把服务器不经常使用的session对象暂时序列化到系统文件,整个的过程是由服务器自动完成的
3,Tomcat中两种Session钝化管理器
session钝化机制是由sessionManager管理
1)StandarManager
org.apache.catalina.session.StandarManager
当Tomcat服务器关闭或者重启时tomcat服务器会将当前内存中的session对象钝化到服务器文件系统中;
另一种情况是web应用程序被重新加载时,内存中的session对象也会被钝化到服务器的文件系统中
2)Persistentmanager
org.apache.catalina.session.Persistentmanager
首先在钝化的基础上进行扩张,第一种情况如上面1,第2种如2,第3种情况,可以配置主流内存的session对象数目,将不长使用的session对象保存到系统文件或数据库,当用时再重新加载
默认情况下,Tomcat提供2个钝化驱动类
4,servlet规范:
接口:HttpServletBindingListener
HttpSessionActionListener
5,实例部分:
当对象实现Persistentmanager的接口之后,这个对象被session绑定了,这时会触发事件,执行方法
servlet3.0下监听器的使用
1,使用3.0的前提条件:1)使用servlet3.0新标准jar包
2)JDK必须在1.6以上版本
3)编译器的编译级别为6.0
4)在web.xml文件中,使用3.0规范
5)使用支持servlet3.0特性的web容器,比如tomcat7,6是不行的
2,监听器的用法:
只需加入注解就可以了,该注解用于将类声明为监听器,被@webListener标注的类必须实现以下至少一个接口:
ServletContextListener
ServletContextAttributeListener
ServletRequestListener
ServletRequestAttributeListener
HttpSessionListener
HttpSessionAttributeListener
3,@WebListener的常用属性
<listener>
<listener-class>footmark.servlet.SimpleListener</listener-class>
</listener>
@@WebListener("this is only a demo listener")
public class SimpleListener implements ServletContextListener{...}
项目案例:统计在线人数
entity.User.java
package entity;
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;
}
}
listener.MyHttpSessionListener.java HttpSessionListener
package listener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.SimpleFormatter;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import util.SessionUtil;
import entity.User;
public class MyHttpSessionListener implements HttpSessionListener {
private int userNumber = 0; //在线人数
public void sessionCreated(HttpSessionEvent arg0) {
userNumber ++;
arg0.getSession().getServletContext().setAttribute("userNumber",userNumber);
}
public void sessionDestroyed(HttpSessionEvent arg0) {
userNumber --;
arg0.getSession().getServletContext().setAttribute("userNumber",userNumber);
ArrayList<User> utils=(ArrayList<User>) arg0.getSession().getServletContext().getAttribute("userNumber");
if(SessionUtil.getUserBySessionId(utils, arg0.getSession().getId())!=null)
{
utils.remove(SessionUtil.getUserBySessionId(utils, arg0.getSession().getId()));
}
}
}
listener.MyServletRequestListenerjava ServletRequestListener
package listener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import util.SessionUtil;
import entity.User;
public class MyServletRequestListener implements ServletRequestListener{
private ArrayList<User> userList;//在线用户List
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 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);
}
sre.getServletContext().setAttribute("userList", userList);
}
}
util.SessionUtil.java
package util;
import java.util.ArrayList;
import 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;
}
}
index.jsp
<body>
当前在线用户人数:${userNumber }<br/>
<%
ArrayList<entity.User> userList = (ArrayList<entity.User>)request.getServletContext().getAttribute("userList");
if(userList!=null){
for(int i = 0 ; i < userList.size() ; i++){
com.imooc.entity.User user = userList.get(i);
%>
IP:<%=user.getIpString() %>,FirstTime:<%=user.getFirstTimeString() %>,SessionId:<%=user.getSessionIdString() %> <br/>
<%}} %>
</body>
web.xml 两个监听器
<listener><listener-class>listener.MyHttpSessionListener</listener-class>
</listener>
<listener>
<listener-class>MyServletRequestListener</listener-class>
</listener>
问题:
1.getServletContext() is undefined for the type HttpServletRequest
必须是tomcat7.0,否则会出现这个错误2.未解决
User.javapublic class User implements HttpSessionBindingListener ,HttpSessionActivationListener,Serializable{
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("sessionDidActivate "+se.getSource());
}
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("sessionWillPassivate "+se.getSource());
}
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("valueBound"+arg0.getName());
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("valueUnbound"+arg0.getName());
}
}
index.jsp
<%request.getSession().setAttribute("currentname",new User());
%>
为何关闭或重启服务器还是没有sessionWillPassivate和sessionDidActivate还是没有执行?