一、监听器
监听器即监视域对象的创建与销毁以及域对象的属性的变化。
1、监听域对象创建与销毁的监听器
举例:ServletContextListener
(1)编写一个监听器去实现相应的接口并覆盖相应的方法:
package pers.zhb.test;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextListenerDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("监听器创建了");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("监听器销毁了"); } }
监听ServletContext域对象的创建与销毁:实现ServletContextListener 接口
监听HttpSession域对象的创建与销毁:实现HttpSessionListener 接口(在Session被创建的时候监听器被创建)
监听ServletRequest域对象的创建与销毁:实现ServletRequesttListener 接口
监听ServletContext域对象属性:实现ServletContextAttributeListener 接口
监听HttpSession域对象属性:实现HttpSessionAttributeListener 接口
监听ServletRequest域对象属性:实现ServletRequestAttributetListener 接口
(2)在web.xml文件中配置:
<listener>
<listener-class>pers.zhb.test.ServletContextListenerDemo</listener-class>
</listener>
即类的全路径。
(3)ServletContextListener 生命周期:服务器开启的时候创建,服务器关闭的时候销毁。
2、监听三大域对象的属性变化
(1)创建Servlet对ServletContext的属性进行设置:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.setAttribute("name", "zhai");//添加
context.setAttribute("name", "zhang");//修改
context.removeAttribute("name");//删除
}
(2)创建监听器检测属性的变化:
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.print("添加:"+servletContextAttributeEvent.getName());
System.out.println(servletContextAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.print("删除:"+servletContextAttributeEvent.getName()); System.out.println(servletContextAttributeEvent.getValue()); } @Override public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.print("修改"+servletContextAttributeEvent.getName()); System.out.println(servletContextAttributeEvent.getValue()); } }
(3)配置文件:
<listener>
<listener-class>pers.zhb.test.ServletContextAttributeListenerDemo</listener-class>
</listener>
<servlet>
<servlet-name>ServletContextAttributeListenerServlet</servlet-name>
<servlet-class>pers.zhb.test.ServletContextAttributeListenerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletContextAttributeListenerServlet</servlet-name>
<url-pattern>/abc</url-pattern>
</servlet-mapping>
(4)被监听的对象的获取:
public class ServletContextListenerDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext servletContext=servletContextEvent.getServletContext();
Object servletContext1=servletContextEvent.getSource();
}
二、对象感知监听器
与session中绑定的对象相关。
1、session的绑定与解绑
(1)创建Person类,实现HttpSessionBindingListener 接口,用来监听session对象的绑定与解绑:
package pers.zhb.domain;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class Student implements HttpSessionBindingListener {
private String studentno;
private String sname;
private String sex;
@Override
public String toString() {
return "Student{" +
"studentno='" + studentno + '\'' +
", sname='" + sname + '\'' +
", sex='" + sex + '\'' +
'}';
}
public String getStudentno() {
return studentno;
}
public void setStudentno(String studentno) {
this.studentno = studentno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("Student对象被绑定了。");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("Student对象被解绑了");
}
}
(2)创建Servlet,向Session中添加对象元素,并将对象元素移除:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Student student=new Student();
student.setSex("男");
student.setSname("zhai");
student.setStudentno("20171514141");
HttpSession session=request.getSession();
session.setAttribute("student",student);
session.removeAttribute("student");
}
与域对象监听器不同,对象感知监听器不需要在web.xml文件中进行配置。
2、session对象的钝化与活化
钝化:将Session中的对象持久化存储到磁盘上。
活化:将磁盘上的对象再次恢复到Session内存中。
(1)钝化:在Student类中实现HttpSessionActivationListener接口,用来监听Session中的对象的钝化与活化。
package pers.zhb.domain;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
public class Student implements HttpSessionActivationListener , Serializable {
private String studentno;
private String sname;
private String sex;
@Override
public String toString() {
return "Student{" +
"studentno='" + studentno + '\'' +
", sname='" + sname + '\'' +
", sex='" + sex + '\'' +
'}';
}
public String getStudentno() {
return studentno;
}
public void setStudentno(String studentno) {
this.studentno = studentno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
System.out.println("session域中的对象被钝化了");
}
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println("Session域中的对象被活化了");
}
}
(2)创建一个Servlet将Student对象存放到Session域中:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Student student=new Student();
student.setSex("男");
student.setSname("zhai");
student.setStudentno("20171514141");
HttpSession session=request.getSession();
session.setAttribute("student",student);
System.out.println("Student对象已经被放到Session域当中了");
}
(3)钝化过程:先访问Servlet,将Student对象存放到Session中,关闭服务器的时候被钝化。可以在服务器work文件夹下面查看。(.ser文件)
(4)将不经常用的Session对象钝化到磁盘上:
在META-INF目录下,创建context.xml文件,可以通过设置时间将Session中存储的对象自动钝化:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- maxIdleSwap:session中的对象多长时间不使用就钝化 -->
<!-- directory:钝化后的对象的文件写到磁盘的哪个目录下 配置钝化的对象文件在 work/catalina/localhost/钝化文件 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="dunhua" />
</Manager>
</Context>
三、在线人数统计
1、书写类在类中创建加减方法
public class OnLineListener {
public static long onLineCounter=0;
public static void addCounter(){
onLineCounter++;
}
public static void reduceCounter(){
onLineCounter--;
}
public static long getOnLineCounter(){
return onLineCounter;
}
}
2、创建监听器类,实现相应的接口
public class MyListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
OnLineListener.addCounter();
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
OnLineListener.reduceCounter();
}
}
3、在配置文件中配置监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<listener>
<listener-class>pers.zhb.listener.MyListener</listener-class>
</listener>
</web-app>
4、创建一个jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="pers.zhb.listener.OnLineListener" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%=OnLineListener.getOnLineCounter()%>
</body>
</html>
jsp页面默认是有session对象的(内置对象),因此访问该页面后session的数量就加一,关闭浏览器(或服务器/超过规定的时间)的时候该session消失
5、测试
(1)用谷歌访问jsp页面:
上一个浏览器页面没有关闭的情况下,火狐访问该页面:
(2)关闭服务器重新访问,在线数量重最小数量开始计数