up:: 监听器的第一个范例
本篇博客主要介绍:监听器的应用于三大内置对象的创建以及销毁;内置对象中属性的新增和删除;
一:简介
监听器中六中常用接口:对象监听接口;(对象中的)属性监听接口:
如果对三大内置对象不清楚了,可以查看Java Web三大作用域对象这篇博客;
二:三个内置对象的监听器(内置对象的创建和销毁)
第二部分,主要展示,监听器可以监听“对象的创建”和“对象的销毁”;;;主要观察整个过程啦!
1.案例内容:
首先,编写一个Servlet:HelloServlet :
这个Servlet中,设置了ServletContext,HttpSession,HttpServletRequest三个对象的属性;
package com.imooc.listener;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloServlet
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().println("This is HelloSerrvler!");
// 得到应用程序全局对象;并在其中设置一个属性;
request.getServletContext().setAttribute("sc-attr1", "sc-attr-value1");
// 得到用户会话对象;并在其中设置一个属性;
request.getSession().setAttribute("session-attr1", "session-attr-value1");
// 在请求对象中设置一个属性;
request.setAttribute("request-attr1", "request-attr-value1");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
然后,编写监听器类:WebListener :
实现了ServletContextListener,HttpSessionListener,ServletRequestListener三个接口,,每个接口都有两个方法需要实现(分别是创建和销毁的操作)
package com.imooc.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* WebListener类实现ServletContextListener接口,以使该监听器类可以监听ServletContext对象;
* WebListener类实现HttpSessionListener接口,以使该监听器类可以监听HttpSession对象;
* WebListener类实现ServletRequestListener接口,以使该监听器类可以监听ServletRequest对象;
* @author Administrator
*
*/
public class WebListener implements ServletContextListener,HttpSessionListener,ServletRequestListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("ServletContext已经被销毁。");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("ServletContext已经被初始化。");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
// TODO Auto-generated method stub
// se:HttpSessionEvent对象(即HttpSession事件对象),这个se参数可以调用方法,获取到已经被创建的Session对象;
HttpSession session = se.getSession();
System.out.println("Session已经被创建,SessionID为:"+session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Session已经被销毁。");
}
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
System.out.println("HttpServletRequest请求对象已经被销毁。");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
// TODO Auto-generated method stub
// sre可以获取ServletRequest请求对象,这儿需要强转一下,转成HttpServletRequest类型的;
HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
System.out.println("HttpServletRequest请求对象已经被创创建,uri是:"+request.getRequestURI());
}
}
最后,在web.xml中配置监听器 :
2.启动应用,观察效果:
首先,打开浏览器,发起一次请求:
并打开浏览器,访问上面的Servlet:这个过程,发起了一个请求,会创建一个HttpServletRequest对象;自然这是打开了一个会话,也附带会创建一个HttpSession对象;(具体原理见:用户会话Session对象这篇博客的Session原理解释部分)
访问localhost:8080/listener-interface/hello这个地址的时候,一个HttpServletRequest对象就会被创建;;;因为这是一个新的浏览器窗口发来的请求,所以Tomcat会为其创建一个新的Session对象;;;;紧接着,Servlet处理完成,伴随着响应的输出,刚才创建的HttpServletRequest对象就被销毁了;;;(这几个创建和销毁的过程,自然会触发监听器中对应的方法啦)
然后,关闭浏览器窗口,重新发起请求:
如果此时,关闭浏览器,重新访问localhost:8080/listener-interface/hello:
关闭浏览器窗口时,并不会触发Session对象销毁的操作,这是因为客户端关闭了,只是客户端通信的SessionnId凭证不存在了,而存在于服务器的这个Session对象还是存在的(30min后自动过期,或者人为调用Session销毁的方法来销毁它):
假如,如果不关闭浏览器窗口,而是刷新界面:
最后,关闭应用:
疑问??????为什么,关闭应用的时候,没有调用销毁Session的方法???,解决后,回头补上。。。
三:属性的监听器(内置对象属性的新增和删除)(属性监听器实际中用的不多)
注:属性监听接口,在实际项目中使用的不多,所以这儿一般性了解即可 。
1.准备工作;增添属性
编写属性的监听器:WebAttributeListener:其中每一个对象的属性接口中,需要实现Add新增方法;Removed删除方法;Replaced修改方法;
package com.imooc.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class WebAttributeListener implements ServletContextAttributeListener,HttpSessionAttributeListener,ServletRequestAttributeListener{
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
// TODO Auto-generated method stub
// event.getName(); // 用于获取新增属性的名称;
// event.getValue();// 获取新增属性的值;
System.out.println("ServletContext对象新增属性了。"+event.getName()+":"+event.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
// TODO Auto-generated method stub
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
// TODO Auto-generated method stub
}
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("HttpSession对象新增属性了。"+event.getName()+":"+event.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
}
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
// TODO Auto-generated method stub
System.out.println("HttpServletRequest对象新增属性了。"+event.getName()+":"+event.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
// TODO Auto-generated method stub
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
// TODO Auto-generated method stub
}
}
在web.xml配置监听器:
启动应用:访问localhost:8080/listener-interface/hello:
2.属性更新;删除(这两个更少用的到,先有个印象就好啦)
属性的更新: 自然,接上,当已经访问了localhost:8080/listener-interface/hello的时候,再次刷新界面(即再次访问localhost:8080/listener-interface/hello),这个过程自然会重新执行Servlet中给对象中属性赋值的语句,这个给属性重新复制就是修改值啦:
属性的删除: 为了演示效果,在Servlet中添加一个删除属性的语句;然后在监听器的删除方法中添加一个输出语句:
效果: