JavaWeb(六)Listener监听器
监听器
监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
Servlet监听器
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession 和 ServletRequest 这三个域对象。
Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。
- 监听三个域对象创建和销毁的事件监听器
- 监听域对象中属性的增加和删除的事件监听器
- 监听绑定到 HttpSession 域中的某个对象的状态的事件监听器。
编写监听器
和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。
和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。
一个 web.xml 文件中可以配置多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。
ServletContext监听器
ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。
当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法
当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
servletContext域对象何时创建和销毁:
- 创建:服务器启动针对每一个web应用创建servletcontext
- 销毁:服务器关闭前先关闭代表每一个web应用的servletContext
package com.hanqi.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class TestApplicationListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("application对象销毁");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("创建application对象");
}
}
访问时会在控制台打印“创建application对象”
HttpSession监听器
HttpSessionListener接口用于监听HttpSession的创建和销毁
创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用。
销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用。
Session域对象创建和销毁的时机创建:用户每一次访问时,服务器创建session
- 销毁:如果用户的session 30分钟没有使用,服务器就会销毁session,我们在web.xml里面也可以配置session失效时间
ServletRequest 监听器
ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁。
Request 对象被创建时,监听器的requestInitialized方法将会被调用。
Request对象被销毁时,监听器的requestDestroyed方法将会被调用。
servletRequest域对象创建和销毁的时机:
- 创建:用户每一次访问,都会创建一个reqeust
- 销毁:当前访问结束,request对象就会销毁
当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
各个域属性监听器中的完整语法定义为:
- public void attributeAdded(ServletContextAttributeEvent scae)
- public void attributeAdded (HttpSessionBindingEvent hsbe)
- public void attributeAdded(ServletRequestAttributeEvent srae)
监听三个域的属性变化
Servlet规范定义了监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。
这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener ServletRequestAttributeListener
这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。
当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
各个域属性监听器中的完整语法定义为:
- public void attributeAdded(ServletContextAttributeEvent scae)
- public void attributeAdded (HttpSessionBindingEvent hsbe)
- public void attributeAdded(ServletRequestAttributeEvent srae)
当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法进行相应
各个域属性监听器中的完整语法定义为:
- public void attributeRemoved(ServletContextAttributeEvent scae)
- public void attributeRemoved (HttpSessionBindingEvent hsbe)
- public void attributeRemoved (ServletRequestAttributeEvent srae)
当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法进行相应
各个域属性监听器中的完整语法定义为:
- public void attributeReplaced(ServletContextAttributeEvent scae)
- public void attributeReplaced (HttpSessionBindingEvent hsbe)
- public void attributeReplaced (ServletRequestAttributeEvent srae)
例子:
package com.hanqi.listener.attr;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
public class TestRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent arg0) {
System.out.println("request对象添加属性");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent arg0) {
System.out.println("移除request属性");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent arg0) {
System.out.println("替换request属性");
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setAttribute("hanqi", "淄博汉企");//设置request属性
request.removeAttribute("hanqi");移除request属性
session.getCreationTime();//获取session的创建时间
%>
<h1>首页</h1>
<hr>
当前在线人数: <%=application.getAttribute("userCount") %>
<hr>
用户列表:
User [sessionid, session创建时间]
</body>
</html>

应用:统计在线用户数量和用户信息
package com.util;
import java.util.Date;
public class User {
private String sid;
private Date stime;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public Date getStime() {
return stime;
}
public void setStime(Date stime) {
this.stime = stime;
}
@Override
public String toString() {
return "User :sid=" + sid + ", stime=" + stime + "|";
}
}
package com.listener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import com.util.User;
/**
* Application Lifecycle Listener implementation class SessionListener
*
*/
@WebListener
public class SessionListener implements HttpSessionListener {
private int userCount;//记录在线人数
private ArrayList<User> userList;//记录在线人的信息
/**
* Default constructor.
*/
public SessionListener() {
// TODO Auto-generated constructor stub
}
/**
* @see HttpSessionListener#sessionCreated(HttpSessionEvent)
*/
//session创建时的方法
public void sessionCreated(HttpSessionEvent sessionEvent) {
// TODO Auto-generated method stub
userCount++;//用户每一次访问时,服务器创建session,用户数量+1
if(userList==null) {
userList = new ArrayList<User>();
}
//获取HttpSession,便于显示,不用每一次都调用
HttpSession session = sessionEvent.getSession();
String sessionid = session.getId();//获取唯一ID
long stime = session.getCreationTime();//获取创建时间
//调用方法查看是不是已经存在的用户,如果不存在,新建用户存入信息,加到集合中
if(!checkUsersSession(sessionid, userList)) {
User u = new User();
u.setStime(new Date(stime));
u.setSid(sessionid);
userList.add(u);
}
//设置session属性,在线人数和在线信息
session.getServletContext().setAttribute("userCount", userCount);
session.getServletContext().setAttribute("userList", userList);
}
private boolean checkUsersSession(String sessionid, ArrayList<User> userList2) {
//查看是不是已经存在的用户,遍历集合,如果集合中有某个元素的id等于传入的id,返回true
for(User u : userList2) {
if(u.getSid().equals(sessionid)) {
return true;
}
}
return false;
}
/**
* @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
*/
//session销毁时的方法
public void sessionDestroyed(HttpSessionEvent sessionEvent) {
//用户下线,人数-1
userCount--;
HttpSession session = sessionEvent.getSession();
String sessionid = session.getId();
System.out.println(sessionid + "的用户下线");
//获取销毁的用户的sessionid,在从集合中找到,移除
if(checkUsersSession(sessionid, userList)) {
Iterator<User> iter = userList.iterator();
while(iter.hasNext()) {
User u = iter.next();
if(u.getSid().equals(sessionid)) {
iter.remove();
}
}
}
session.getServletContext().setAttribute("userCount", userCount);
session.getServletContext().setAttribute("userList", userList);
}
}
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.ArrayList,com.util.User"%>
<%@ page import="java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
当前在线人数: <%=application.getAttribute("userCount") %>
<hr>
在线用户列表:<br>
<%
List<User> userList = (List<User>)application.getAttribute("userList");//获取application对象,用户信息集合
if(userList!=null) {//如果集合不为空,遍历显示
for(User u : userList) {
out.print(u+"<br>");
}
}
%>
</body>
</html>
尝试加一个踢人推出的功能
JavaWeb(六)Listener监听器的更多相关文章
- JavaWeb之Listener监听器
监听在Java体系中运用的很广泛,在安卓开发.JavaWeb开发中到处存在,在其他语言也有类似的,如果有了解过设计模式那很容易理解实现的原理.不过对于开发者来说,使用观察者模式只需实现相应的接口就好, ...
- 转-JavaWeb三大组件之Listener监听器
JavaWeb三大组件之Listener监听器一.概述1,它是一个接口,内容由我们来实现 2,它需要注册,例如注册在按钮上 3,监听器中的方法,会在特殊事件发生时被调用 二.JavaWeb中的监听器1 ...
- javaweb学习总结—监听器(Listener)
监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一 ...
- Listener监听器与Filter过滤器
1.Listener [1]监听器简介 > Listener是JavaWeb的三大组件之一,Servlet.Filter.Listener > Li ...
- 第16 天 JavaWEB过滤器和监听器技术
Day16 JavaWEB过滤器和监听器技术 复习: 1.大结果集分页mysql的实现,是使用那个关键字,从user表中取第一页的数据,长度为10,sql语句怎么写? 2.分页查询的起始位置(star ...
- 超全面的JavaWeb笔记day20<监听器&国际化>
JavaWeb监听器 三大组件: l Servlet l Listener l Filter Listener:监听器 1. 初次相见:AWT 2. 二次相见:SAX 监听器: l 它是一个接口,内容 ...
- JavaWEB过滤器和监听器技术
过滤器介绍 什么是过滤器 生活中的例子: 滤水器,口罩,杯子上滤网,渔网 生活中的过滤器:留下我们想要的,排除,我们不想要的. 高考: 只有分数够高的同学才能进入理想的大学.有一部分同学被拦截在大学之 ...
- JavaWeb——过滤器及监听器
什么是过滤器? 过滤器示意图 Filter是如何实现拦截的? Filter的生命周期 Filter的创建 Filter的销毁 FilterConfig接口 Servlet过滤器有关接口 过滤器配置 F ...
- .jsp文件的使用和理解以及一些小练习和Listener监听器
什么是 jsp,它有什么用? jsp 的全换是 java server pages.Java 的服务器页面.jsp 的主要作用是代替 Servlet 程序回传 html 页面的数据.因为 Servle ...
- 十:JavaWeb中的监听器(一)
2.1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域 ...
随机推荐
- openjudge8465:马走日 [搜索]
描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入 第一行为整数T ...
- java内存区域——深入理解JVM读书笔记
本内容由<深入理解java虚拟机>的部分读书笔记整理而成,本读者计划连载. 通过如下图和文字介绍来了解几个运行时数据区的概念. 方法区:它是各个线程共享的区域,用于内存已被VM加载的类信息 ...
- (转)使用BigDecimal进行精确运算
场景:在进行支付业务的金额计算时,通常采用BigDecimal类型的数据,并没有看到常见的int double类型,所以有必要好好学习下BigDecimal的常用用法. 1 误区 首先我们先来看如下代 ...
- 动态rem与1px边框问题的理解
当我们在项目开发中,拿到设计师的设计图,满怀欣喜的准备按照设计图将页面实现出来的时候,我们通常会遇到这个问题: 如何将页面的内容按照在不同手机屏幕浏览的情况下,比例都是不变的呢?这个时候我们就需要使用 ...
- github、gitlab 管理多个ssh key
第一种方法: 通过 git 命令行来操作 1.cd ~/.ssh 2.ls 注:如果.ssh 目录下有文件存在那么表示之前添加过 3. ssh-keygen -t rsa -C "xxxxx ...
- 简单工厂设计模式--Java设计模式(一)
一 概念: 简单工厂模式就是通过一个工厂类根据参数动态创建对应的类. 二 案例 我们以汽车作为例子,在现实生活中汽车只是一个抽象的产品,其中有很多类型的汽车才是具体产品,如奔驰.宝马.保时捷等等(当然 ...
- 简陋的 ASP.NET CORE 单页Web应用程序“框架”
我对ASP.NET CORE了解不多,不知道是不是重复造轮子,也或者什么也不是,这个Demo是这样的: 1.非常简单或者说原始:2.将单页Web应用增加了一个页(Page)概念(相当于MVC的 Vie ...
- 关于Java JDK中 URLDecoder.decode 方法
java.net.URLDecoder.decode 在项目中碰到了个比较奇怪的问题,就是我在本地使用java.net.URLDecoder.decode(ruleName)方法解码,没有问题,本地的 ...
- PAT (Basic Level) Practise (中文) 1023. 组个最小数 (20)
1023. 组个最小数 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定数字0-9各若干个.你可以以 ...
- 数据结构二叉树的所有基本功能实现。(C++版)
本人刚学数据结构,对树的基本功能网上找不到C++代码 便自己写了一份,贴出方便大家进行测试和学习. 大部分功能未测试,如有错误或者BUG,请高手们指教一下,谢谢. 结点声明: BinTreeNode. ...