JavaWeb开发Listener学习

发布于:2022-12-22 ⋅ 阅读:(384) ⋅ 点赞:(0)

博主信息:

📢@博主: 嘟嘟的程序员铲屎官
💬:一位爱喵咪,爱开源,爱总结,爱分享技术的Java领域新星博主,如果你想和博主做朋友,关注博主,并私聊博主(给我发一条消息我就会关注你喔),博主本人也十分喜欢解决问题,如果你有什么问题,也可以来私聊博主喔,希望能够和C站的朋友相互学习,相互进步。
💬:关于本篇博客,最近在学习JavaWeb部分的知识,对<<JavaWeb入门经典>>本书第7章第5节Listener监听器进行个人总结,如果有什么错误的,请各位大佬能够及时提出,以免小弟误人子弟!

一.Listener监听器

1.什么是Listener监听器

在Servlet技术中定义很多的事件,为了对这些事件进行处理,针对这些事件编写相关的事件监听器,从而使用监听器处理事件,本篇博客主要讲解三大域对象(ServletContext、HttpSession、ServletRequest)的监听器,三大域对象的监听器分别对应的事件ServletContextEvent(上下文事件),HttpSessionEvent(会话事件),
HttpServletRequestEvent(请求事件)。

2.Listener简介

通过Listener接口对事件进行监听,下表列出常用8个Listener接口和6个Event类
在这里插入图片描述
在这里插入图片描述

servlet-api.jar中一共有13个和Listener相关的.java

在这篇博客<<JavaWeb开发Filter学习>>下第3.Filter的核心对象知识点中我们对servlet-api.jar进行了解压,并对javax.servlet包下的*.class文件进行了反编译,我们看看在servlet反编译文件下有哪一些Java文件跟Listener相关。

在javax.servlet包下和Listener相关的.Java文件(7个):
进入到servlet反编译文件中
在这里插入图片描述
在文件搜索框中输入*listener*

在这里插入图片描述
在原包(javax.servlet解压包)中进行我们可以发现annotation和http文件都存在以Listener相关的.class文件,分别对这二个包进行反编译
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在javax.servlet.annotation包下和Listener相关的.Java文件(1个):
在这里插入图片描述

在javax.servlet.http包下和Listener相关的.class文件(5个):
由于http包下的.class文件有的没有反编译成功,所以就在原包中进行搜索与Listener相关的.class
在这里插入图片描述

3.使用监听器

使用监听器有以下二个步骤:

  • 创建监听器(只要创建一个实现相关接口的Java类即可)
  • 注册监听器

注册监听器的二种方式:
使用@webListener标签进行注册
在这里插入图片描述

在web.xml中使用部署描述符进行注册 在这里插入图片描述

4.Servlet Context监听器

Servlet Context监听器可以监听ServletContext对象的创建、删除和添加属性,以及删除和修改操作,该监听器需要用到如下两个接口,该接口都是javax.servlet包下的成员。

(1) ServletContextListener接口
  • 该接口位于javax.servlet下
  • 主要监听ServletContext的创建和删除。
  • 它提供了二个抽象方法:
    contextInitialized();contextDestroyed()
    在这里插入图片描述
    在这里插入图片描述

<<JavaWeb入门经典>>本书对这二个抽象方法的解释:
在这里插入图片描述

(2) ServletAttributeListener接口
  • 该接口位于javax.servlet下
  • 主要监听ServletContext属性的增加、删除及修改
  • 它提供了3个抽象方法:
    attributeAdded();attributeRemoved();attributeReplaced()

在这里插入图片描述

在这里插入图片描述
<<JavaWeb入门经典>>本书对这三个抽象方法的解释:
在这里插入图片描述

5.Session 监听器

与HttpSession有关的监听器接口有4个:HttpSessionListener、HttpSessionActivation-Listener、HttpSessionAttributeListener和 HttpSessionBindingListener。这些接口都是javax.servlet.http包的成员,下面将进行详细的讲解。

(1) HttpSessionListener接口
  • 该接口位于javax.servlet.http包下
  • 该接口监听HTTP会话的创建及销毁,它提供了如下两个抽象方法。
    sessionCreated();sessionDestroyed()

在这里插入图片描述
在这里插入图片描述

<<JavaWeb入门经典>>本书对这二个抽象方法的解释:
在这里插入图片描述
在这里插入图片描述

(2) HttpSessionAttributeListener接口
  • 该接口位于javax.servlet.http包下
  • 该接口实现监听 HTTP会话中属性的设置请求(属性添加,删除,替换),它提供了如下三个方法。
    attributeAdded();attributeRemoved();attributeReplaced();
    在这里插入图片描述
    在这里插入图片描述

<<JavaWeb入门经典>>本书对这三个抽象方法的解释:
在这里插入图片描述

(3) HttpSessionActivationListener接口
  • 该接口位于javax.servlet.http包下
  • 该接口实现监听HTTP会话active和 passivate情况,它提供了如下2个方法。
    sessionWillPassivate();sessionDidActivate()

在这里插入图片描述
在这里插入图片描述
<<JavaWeb入门经典>>本书对这二个抽象方法的解释:
在这里插入图片描述

(4) HttpSessionBindingListener接口
  • 该接口位于javax.servlet.http包下
  • 该接口实现监听HTTP会话中对象的绑定信息,它是唯一不需要在web.xml中设置Listener的,并提供了以下两个方法。
    valueBound();valueUnbound();

在这里插入图片描述
在这里插入图片描述
<<JavaWeb入门经典>>本书对这二个抽象方法的解释:
在这里插入图片描述

6.ServletRequest 监听器

在ServletRequest级别上有3个监听器接口:ServletRequestListener、ServletRequestAttributeListener和AsyncListener,这些接口都是javax.servlet包的成员。下面主要讲解了前二种接口。

(1) ServletRequestListener接口
  • 该接口位于javax.servlet包下
  • ServletRequestListener对 ServletRequest的创建和销毁做出响应。
  • 该接口提供如下二个方法
    requestDestroyed();requestInitialized();

在这里插入图片描述
在这里插入图片描述
<<JavaWeb入门经典>>本书对这二个抽象方法的解释:
在这里插入图片描述

(2) ServletRequestAttributeListener接口
  • 该接口位于javax.servlet包下
  • 当在ServletRequest中添加删除或者替换某个属性时会调用以下三个方法
    attributeAdded();attributeRemoved();attributeReplaced();
    在这里插入图片描述

在这里插入图片描述
<<JavaWeb入门经典>>本书对这三个抽象方法的解释:
在这里插入图片描述

7.实例练习(使用监听器统计在线用户及人数)

分析:
在这里插入图片描述

项目结构:
在这里插入图片描述
index.html
在这里插入图片描述
web.xml
(在web.xml中配置session-timeout标签 标志session过期时间为1分钟 0为不过期)
在这里插入图片描述
HttpSessionListener.java

@WebListener
public class HttpSessionListener implements javax.servlet.http.HttpSessionListener{

	private int userCounts=0;
	@Override
	public void sessionCreated(HttpSessionEvent httpSessionEvent) {
		// TODO Auto-generated method stub
		httpSessionEvent.getSession().setAttribute("userCounts", ++userCounts);
		
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
		// TODO Auto-generated method stub
		// 将人数数据加到HttpSession中
		httpSessionEvent.getSession().setAttribute("userCounts", --userCounts);
		
		// 获取用户列表
		@SuppressWarnings("unchecked")
		ArrayList<User> list=(ArrayList<User>)httpSessionEvent.
				getSession().getServletContext().getAttribute("userList ");
		
		
		if (list!=null) {
			// 根据SessionId属性将当前用户从userList集合中移除
			for (User user : list) {
				if (user.getSessionId().equals(httpSessionEvent.getSession().getId())) {
					list.remove(user);
				}
			}	
		}
	}
	


}

ServletRequestListener.java


@WebListener
public class ServletRequestListener implements javax.servlet.ServletRequestListener{

	@Override
	public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void requestInitialized(ServletRequestEvent servletRequestEvent) {
		// TODO Auto-generated method stub
		// 获取ServletContext中的userList集合
		@SuppressWarnings("unchecked")
		ArrayList<User> list=(ArrayList<User>)servletRequestEvent.getServletContext().getAttribute("userList");
		// ServletContext是否创建,未创建返回的集合为null,需要进行初始化
		if (list==null) {
			list=new ArrayList<>();
		}
		// 创建HttpServletRequest对象
		HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequestEvent.getServletRequest();
		
		// 当前用户是否在该集合中,没有则将用户信息加入到集合中去,并保存到ServletContext中
		if (noAtUserList(list,httpServletRequest)) {
			// 将当前用户添加到userList集合中
			User user=new User();
			user.setSessionId(httpServletRequest.getSession().getId());
			user.setIp(httpServletRequest.getRemoteAddr()); 
		    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:MM:ss"); 
		    user.setFirstTime(sdf.format(new Date())); 
		    list.add(user); 
		}
		
		// 将数据保存到ServletContext中
		servletRequestEvent.getServletContext().setAttribute("userList", list);
	}
	
	@SuppressWarnings("unused")
	private boolean noAtUserList(ArrayList<User>list,HttpServletRequest httpServletRequest) {
		for (User user : list) {
			if (user.getSessionId().equals(httpServletRequest.getSession().getId())) {
				return false;
			}
		}
		return true;
	}

}

User.java

public class User { 
	  // 当前用户的session id 
	  private String sessionId; 
	  // 当前用户的ip地址 
	  private String ip; 
	  // 当前用户第一次访问的时间 
	  private String firstTime; 

	  
	  public String getIp() { 
	    return ip; 
	  } 
	  public void setIp(String ip) { 
	    this.ip = ip; 
	  } 
	  public String getFirstTime() { 
	    return firstTime; 
	  } 
	  public void setFirstTime(String firstTime) { 
	    this.firstTime = firstTime; 
	  } 
	  public String getSessionId() { 
	    return sessionId; 
	  } 
	  public void setSessionId(String sessionId) { 
	    this.sessionId = sessionId; 
	  }
	  
}

usersInfoservlet.java


@SuppressWarnings("serial")
@WebServlet(urlPatterns={"/usersInfo"})
public class usersInfoservlet extends HttpServlet{
		@Override
		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			// TODO Auto-generated method stub
			// 设置网页编码,防止出现乱码
			req.setCharacterEncoding("utf-8");
			resp.setCharacterEncoding("utf-8");
			resp.setHeader("content-type", "text/html;charset=UTF-8");
			
			// 获取userList
			@SuppressWarnings({ "unused", "unchecked" })
			ArrayList<User>userList=(ArrayList<User>)req.getServletContext().getAttribute("userList");
			// 获取当前用户数
			int userCounts=((req.getSession().getAttribute("userCounts") == null) ? 0:(int) req.getSession().getAttribute("userCounts"));

			
			// 显示信息
			PrintWriter writer=resp.getWriter();
			writer.print("<html><head></head>");
			writer.print("<body>当前人数:"+userCounts+"</br>");
			if (userList!=null) {
				for (int i = 0; i < userList.size(); i++) {
					writer.print("第"+(i+1)+"个用户,信息:</br>");
					writer.print("sessionId:"+userList.get(i).getSessionId()+"</br>");
					writer.print("ip:"+userList.get(i).getIp()+"</br>");
					writer.print("firstTime:"+userList.get(i).getFirstTime()+"</br>");
				}
			}
			writer.print("</body></html>");
		}
		
		@Override
		protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
			doGet(req, resp);
		}
}

运行效果:
在这里插入图片描述
在这里插入图片描述
打开另外一个游览器,访问:http://localhost:8085/app05/usersInfo
在这里插入图片描述
再打开一个游览器,再次访问
在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到