1. 监听器Listener
监听器就是监听某个对象的状态变化的组件。监听器的相关概念事件源:
- 被监听的对象(三个域对象request , session , servletContext(Application) )
- 监听器:监听事件源对象, 事件源对象的状态的变化都会触发监听器。
- 注册监听器:将监听器与事件源进行绑定。
- 响应行为:监听器监听到事件源的状态变化时,所涉及的功能代码(程序员编写代码)
按照被监听的对象划分: ServletRequest(Request)域; HttpSession域(Session会话域);ServletContext(Application应用程序域)域。按照监听的内容分:监听域对象的创建与销毁的;监听域对象的属性变化的。
三大域对象的创建与销毁的监听器
ServletContextListener(监听Application应用程序域)
监听ServletContext域的创建与销毁的监听器,Servlet域的生命周期:在服务器启动创建,服务器关闭时销毁;监听器的编写步骤:
- 编写一个监听器类去实现监听器接口
- 覆盖监听器的方法(重写)
ServletContextListener监听器的主要作用:
初始化的工作:初始化对象;初始化数据。
HttpSessionListener(监听Session会话域)
监听Httpsession域的创建与销毁的监听器。HttpSession对象的生命周期 :第一次调用request.getSession时创建;销毁有以下几种情况(服务器关闭、session过期、 手动销毁)
ServletRequestListener(监听Requset请求域)
监听ServletRequest域创建与销毁的监听器。ServletRequest的生命周期 :每一次请求都会创建request ,请求结束则销毁。
监听三大域对象属性变化的域对象的通用方法
- 触发添加属性的监听器的方法
setAttribute(name,value)- 触发修改属性的监听器的方法
removeAttribute(name):触发删除属性的监听器的方法
2. 与session中的绑定的对象相关的监听器(对象感知监听器)
(1)即将要被绑定到session中的对象有几种状态
绑定状态:就是一个对象被放到session域中
解绑状态:就是这个对象从session域中移除了
钝化状态:是将session内存中的对象持久化(序列化)到磁盘
活化状态:就是将磁盘上的对象再次恢复到session内存中
绑定与解绑的监听器HttpSessionBindingListener(接口)
活化与钝化监听器(一定要是一个对象-java类)
META-INF与context文件名一定要一致
注:一个普通的Javabean类只要实现了Serializable(接口),就可以实现活化和钝化;而如果既实现了Serializable(序列化,接口)又实现了HttpSessionActivationListener(接口),那么这个java类不但可以实现活化和钝化,而且还可以知道什么时候被活化和钝化
context.xml
<?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="Javawebtest123"/>
</Manager>
</Context>
钝化文件的路径
C:\Users\liutianyu.IntelliJIdea2019.3\system\tomcat\Tomcat_8_0_21_ListenerDemo\work\Catalina\localhost\ListenerDemo_war_exploded\自定义的文件名
3. 监听器应用举例 --- 统计网站在线人数
主页面 index.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="login.jsp">登录</a>
<a href="ShowUser.do">显示在线用户</a>
</body>
</html>
登录页面 login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<center>
<h3>用户登录</h3>
</center>
<form action="${pageContext.request.contextPath}/LoginServlet" method="post">
<table border="1" width="550px" cellpadding="0" cellspacing="0" align="center">
<tr>
<td height="35" align="center">用户名</td>
<td>
<input type="text" name="username">
</td>
</tr>
<tr>
<td height="35" align="center">密码</td>
<td>
<input type="password" name="password">
</td>
</tr>
<tr>
<td height="35" colspan="2" align="center">
<input type="submit" value="登录">
</td>
</tr>
</table>
</form>
</body>
</html>
查看当前在线用户界面 showuser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="logout.do">登出</a>
<hr>
<p>当前在线用户</p>
<ul>
<c:forEach items="${users}" var="user">
<li>${user.value}</li>
</c:forEach>
</ul>
</body>
</html>
User.java 类
package com.lty.domain;
public class User {
private String username;
private String id;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
单列模式工具类 OnlineUserMap.java
package com.lty.db;
import com.lty.domain.User;
import java.util.HashMap;
import java.util.Map;
public class OnlineUserMap {
// 单列模式 --- 唯一的一个对象,不允许外部在使用该类创建对象
private static OnlineUserMap onlineUserMap = new OnlineUserMap();
private Map<String ,String> stringMap = new HashMap<>();
private OnlineUserMap(){
}
public static OnlineUserMap getInstance(){
return onlineUserMap;
}
public Map<String, String> getStringMap() {
return stringMap;
}
public void setStringMap(Map<String, String> stringMap) {
this.stringMap = stringMap;
}
}
监听器
package com.lty.listener;
import com.lty.db.OnlineUserMap;
import com.lty.domain.User;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.util.HashMap;
import java.util.Map;
@WebListener()
public class OnlineListener implements
HttpSessionListener, HttpSessionAttributeListener {
// Public constructor is required by servlet spec
public OnlineListener() {
}
// -------------------------------------------------------
// HttpSessionListener implementation
// -------------------------------------------------------
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
}
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
// 将当前用户从Map中删除
OnlineUserMap onlineUserMap = OnlineUserMap.getInstance();
System.out.println("sessionDestroyed:" + onlineUserMap.getStringMap().get(se.getSession().getId()));
onlineUserMap.getStringMap().remove(se.getSession().getId());
}
// -------------------------------------------------------
// HttpSessionAttributeListener implementation
// -------------------------------------------------------
public void attributeAdded(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is added to a session.
*/
String attr_name = sbe.getName();
String attr_value = (String)sbe.getValue();
System.out.println(attr_name);
System.out.println(attr_value);
System.out.println(sbe.getSession().getId());
OnlineUserMap onlineUserMap = OnlineUserMap.getInstance();
onlineUserMap.getStringMap().put(sbe.getSession().getId(),attr_value);
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is removed from a session.
*/
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
/* This method is invoked when an attribute
is replaced in a session.
*/
}
}
servlet
登录servlet(session的不激活时间:10s自动销毁)
package com.lty.servlet;
import com.lty.db.OnlineUserMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LoginServlet" , urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
request.getSession().setAttribute("username",username);
request.getSession().setMaxInactiveInterval(10);
request.setAttribute("users", OnlineUserMap.getInstance().getStringMap());
request.getRequestDispatcher("showuser.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
登出servlet
package com.lty.servlet;
import com.lty.db.OnlineUserMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LogoutServlet" , urlPatterns = "/logout.do")
public class LogoutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().invalidate();
request.setAttribute("users", OnlineUserMap.getInstance().getStringMap());
request.getRequestDispatcher("showuser.jsp").forward(request,response);
}
}
查看在线用户
package com.lty.servlet;
import com.lty.db.OnlineUserMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "ShowServlet" , urlPatterns = "/ShowUser.do")
public class ShowServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("users", OnlineUserMap.getInstance().getStringMap());
request.getRequestDispatcher("showuser.jsp").forward(request,response);
}
}