04---servlet11(监听器)

本文详细介绍了Web开发中常用的监听器,包括对application、session及request的监听方式与应用场景,通过具体示例阐述如何实现和配置监听器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

监听:对某一些操作进行监视,那么就称为监听;
在web中的监听主要的功能是用于对ServletConfig、Session、Request进行监听的一种操作;

监听器:
	第三种Servlet程序称为监听Servlet,主要的功能是负责监听WEB的各种操作,当相关的事件触发之后将
	产生事件,并对此事件进行处理,在WEB中可以对application、session、request三种操作进行监听;

1、对application进行监听:
	Application是ServletContext接口的对象,表示的是整个上下文的环境;
		javax.servlet.ServletContext接口;
	   注:application是针对容器的,而不是http协议,所以不像
		request、response:
			request:javax.servlet.http.HttpServletRequest;
			response:javax.servlet.http.HttpServletResponse;
	如果要想实现对application监听则可以使用如下两个接口:
		·ServletContextListener:-----------对整个上下文环境的监控;
		·ServletContextAttributeListener:--对属性的监听;
	在ServletContextListener中有两个方法:
		contextDestroyed(ServletContextEvent sce):-----销毁
		contextInitialized(ServletContextEvent sce):---初始化
	
	·做一个简单的监听,只完成简单的输出;
			package listener.lid.servlet;
			import javax.servlet.*;
			public class ServletContextListenerDemo implements ServletContextListener{
				public void contextInitialized(ServletContextEvent sce){
					System.out.println("**容器初始化-->"+sce.getServletContext().getContextPath());
					}
				public void contextDestroyed(ServletContextEvent sce){
					System.out.println("**容器销毁**");
					}
				}
		编译上面的servlet;
	·配置映射:
		简单的Servlet:<servlet> 、<servlet-mapping>---通过mapping进行访问
		过滤器:<filter>、<filter-mapping>----通过mapping进行过滤,即过滤哪里
		但是现在的监听器就省事了,直接编写<listener>即可;---(即使有mapping也没有意义,不用通过mapping去映射)
		如果现在一个web.xml文件之中包含简单servlet、过滤器、监听器,则建议编写配置的顺序
			·<filter>
			·<filter-mapping>
			·<listener>
			·<servlet>
			·<servlet-mapping>
			
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.ServletContextListenerDemo
		  	</listener-class>
		  </listener>
		重启服务器;
	注意:监听器也是在服务器启动的时候加载初始化的,容器关闭时执行销毁;
	只要是容器的启动和关闭都要触发这些操作;
	
	还可以实现ServletContextAttributeListener接口:

2、对application属性进行监听:
	·编写属性增加的监听:
		package listener.lid.servlet;
		import javax.servlet.*;
		public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener{
				public void attributeAdded(ServletContextAttributeEvent event){
						System.out.println("**增加属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
					}
				public void attributeRemoved(ServletContextAttributeEvent event){
						System.out.println("**移除属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
					}
				public void attributeReplaced(ServletContextAttributeEvent event){
						System.out.println("**替换属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
					}
			}
			编译程序;
	·在web.xml配置监听
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.ServletContextAttributeListenerDemo
		  	</listener-class>
		  </listener>
	·重启服务器;
	·创建网页:
		addAttribute.jsp:
			<%@ page contentType="text/html" pageEncoding="gbk"%>
			<html>
			<head><title>这是测试</title></head>
			<body>
				<%
					this.getServletContext().setAttribute("userName1","lid");
					this.getServletContext().setAttribute("userName2","yuj");
				%>	
				<h3>属性设置完成</h3>
			</body>
			</html>
		removeAttribute.jsp:
			<%@ page contentType="text/html" pageEncoding="gbk"%>
			<html>
			<head><title>这是测试</title></head>
			<body>
				<%
					this.getServletContext().removeAttribute("userName1");
					this.getServletContext().removeAttribute("userName2");
				%>	
				<h3>属性移除完成</h3>
			</body>
			</html>
		在浏览器中输入:http://localhost/lid/listerner/addAttribute.jsp这时会监听到"属性的增加";
		如果不断地刷新该网页:这是会监听的"属性的替换";
		在浏览器中输入:http://localhost/lid/listerner/removeAttribute.jsp这时会监听到"属性的移除";

	
3、对session进行监听:
	在监听器中,针对于session的监听,提供了三个接口:
		·HttpSessionListener
		·HttpSessionAttributeListener
		·HttpSessionBingdingListener
	Session属于HTTP协议的范畴,所以这些接口肯定在javax.servlet.http包中定义的;
	·在HttpSessionListener中定义有两种方法:
		sessionCreated(HttpSessionEvent se)和sessionDestroyed(HttpSessionEvent se);

	·创建一个session监听:
		package listener.lid.servlet;
		import javax.servlet.*;
		import javax.servlet.http.*;
		public class HttpSessionListenerDemo implements HttpSessionListener{
				public void sessionCreated(HttpSessionEvent se){
						System.out.println("**session创建,session id="+se.getSession().getId());
					}
				public void sessionDestroyed(HttpSessionEvent se){
						System.out.println("**session销毁**");
					}
			}
		编译session监听;
	·在web.xml中配置:
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.HttpSessionListenerDemo
		  	</listener-class>
		  </listener>
	·重启服务器;
	通过客户端向服务器发起请求时,session就会创建,这是就会监听到session被创建;
	如果现在想让一个session销毁的话,有两种方法,但是这两种方法并不是通过直接关闭浏览器
	就可以实现的:
		·session的注销方法:invalidate();
		·session的超时:在tomcat中session的超时时间默认的是30分钟;
			在tomcat的目录conf中找到web.xml,在web.xml中有
				   <session-config>
				        <session-timeout>30</session-timeout>
				    </session-config>
			有上面可以看到session的超时时间是30分钟;
		当然我们可以自己配置session的超时时间,即在项目的web.xml中加上
				   <session-config>
				        <session-timeout>30</session-timeout>
				    </session-config>
		注意:如果修改tomcat中的web.xml中的<session-timeout>的话,session的超时范围将应用
			于发布在tomcat中的所有项目;

4、对session属性进行监听:
		package listener.lid.servlet;
		import javax.servlet.*;
		import javax.servlet.http.*;
		public class HttpSessionAttributeListenerDemo implements HttpSessionAttributeListener{
				public void attributeAdded(HttpSessionBindingEvent se){
						System.out.println("**session属性,属性名称="+se.getName()+"属性值"+se.getValue());
					}
				public void attributeRemoved(HttpSessionBindingEvent se){
						System.out.println("**session移除**");
					}
				public void attributeReplaced(HttpSessionBindingEvent se){
						System.out.println("**session替换**");
					}
			}
	配置web.xml:
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.HttpSessionAttributeListenerDemo
		  	</listener-class>
		  </listener>

5、HttpSessionBingdingListener:
	对该接口的监听不用在web.xml中进行配置;

		package listener.lid.servlet;
		import javax.servlet.*;
		import javax.servlet.http.*;
		public class LoginUser implements HttpSessionBindingListener{
				private String name;
				public LoginUser(String name){
						this.setName(name);
					}
				public void valueBound(HttpSessionBindingEvent se){
						System.out.println("**在session中保存LoginUser对象(name="+this.getName()+")");
					}
				public void valueUnbound(HttpSessionBindingEvent se){
						System.out.println("**从session中移除**");
					}
				public String getName(){
						return this.name;
					}
				public void setName(String name){
						this.name=name;
					}
			}

	此处不需要任何配置文件的配置;
			<%@ page contentType="text/html" pageEncoding="gbk"%>
			<%@ page import="listener.lid.servlet.LoginUser"%>
			<html>
			<head><title>这是测试</title></head>
			<body>
				<%
					LoginUser user=new LoginUser("lid");
					session.setAttribute("info",user);//直接保存LoginUser的子类
				%>	
				<h3>属性移除完成</h3>
			</body>
			</html>
	由于此处需要手工绑定,所以才不需要做任何额外的配置;

6、对request监听:
	package listener.lid.servlet;
	import javax.servlet.*;
	public class ServletRequestListenerDemo implements ServletRequestListener{
			public void requestInitialized(ServletRequestEvent sre){
					System.out.println("**request初始化**http://"+sre.getServletRequest().getRemoteAddr()+
						sre.getServletContext().getContextPath());
				}
			public void requestDestroyed(ServletRequestEvent sre){
					System.out.println("**request销毁**");
				}
		}
		编译程序;
	在web.xml中编译;
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.ServletRequestListenerDemo
		  	</listener-class>
		  </listener>

7、对request属性监听:
		package listener.lid.servlet;
		import javax.servlet.*;
		import javax.servlet.http.*;
		public class ServletRequestAttributeListenerDemo implements ServletRequestAttributeListener{
				public void attributeAdded(ServletRequestAttributeEvent se){
						System.out.println("**request属性,属性名称="+se.getName()+"属性值"+se.getValue());
					}
				public void attributeRemoved(ServletRequestAttributeEvent se){
						System.out.println("**request移除**");
					}
				public void attributeReplaced(ServletRequestAttributeEvent se){
						System.out.println("**request替换**");
					}
			}
	在web.xml中配置,
		  <listener>
		  	<listener-class>
		  		listener.lid.servlet.ServletRequestListenerDemo
		  	</listener-class>
		  </listener>
	在实际中对request的监听并不常用,最常用的就是ServletContext、HttpSession监听;

8、监听器的实例:
	经常会在各个站点上看到一些在线人员的列表,实际上此操作可以通过监听来完成;
	在整个的操作中个,需要使用一下几个接口:
	·所有的人员列表应该使用集合保存,但是这个集合所有的用户都能看到,而且以后也要操作,
		那么证明整个监听中必然要有一个application对象保存;
	·用户登陆成功,增加属性,肯定要使用属性监听接口(HttpSessionAttributeListener)
	·当用户离开之后,删除session,所以还要用HttpSessionListener
		package listener.lid.servlet;
		import java.util.*;
		import javax.servlet.*;
		import javax.servlet.http.*;
		public class OnlineUserList implements ServletContextListener,HttpSessionAttributeListener,HttpSessionListener{
				private ServletContext app=null;
				
				public void contextInitialized(ServletContextEvent sce){
					this.app=sce.getServletContext();
					this.app.setAttribute("online",new TreeSet());//准备集合
					}
				public void contextDestroyed(ServletContextEvent sce){}
				public void attributeAdded(HttpSessionBindingEvent se){
					Set all=(Set) this.app.getAttribute("online");
					all.add(se.getValue());
					this.app.setAttribute("online",all);
					}
				public void attributeRemoved(HttpSessionBindingEvent se){
					Set all=(Set)this.app.getAttribute("online");
					all.remove(se.getSession().getAttribute("userid"));
					this.app.setAttribute("online",all);
					}
				public void attributeReplaced(HttpSessionBindingEvent se){}
				public void sessionCreated(HttpSessionEvent se){}
				public void sessionDestroyed(HttpSessionEvent se){
					Set all=(Set)this.app.getAttribute("online");
					all.remove(se.getSession().getAttribute("userid"));
					this.app.setAttribute("online",all);
					}
			}
		在web.xml中配置:
			  <listener>
			  	<listener-class>
			  		listener.lid.servlet.OnlineUserList
			  	</listener-class>
			  </listener>
			  <session-config>
				<session-timeout>1</session-timeout>
			  </session-config>
		重新启动服务器;
	login.jsp界面:
		<%@ page contentType="text/html" pageEncoding="gbk"%>
		<%@ page import="listener.lid.servlet.LoginUser"%>
		<html>
		<head><title>这是测试</title></head>
		<body>
			<form action="login.jsp" method="post">
				用户ID:<input type="text" name="userid">
				<input type="submit" value="登陆">
			</form>
			<%
				String userid=request.getParameter("userid");
				if(!(userid==null||"".equals(userid))){
					session.setAttribute("userid",userid);
					response.sendRedirect("list.jsp");
					}
			%>
		</body>
		</html>
	list.jsp界面:
		<%@ page contentType="text/html" pageEncoding="gbk"%>
		<%@ page import="java.util.*"%>
		<html>
		<head><title>这是测试</title></head>
		<body>
			
			<%
				Set all=(Set) this.getServletContext().getAttribute("online");
				Iterator iter=all.iterator();
				while(iter.hasNext()){
			%>
					<h3><%=iter.next()%></h3>
			<%
					}
			%>
		</body>
		</html>
	还有可能做一些其他的辅助作用等等;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bzuld

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值