Web容器管理Servlet/JSP相关的生命周期,若对HttpServletRequest对象、HttpSession对象、ServletContxt对象在生成、销毁或相关属性设置发生的时机点有兴趣,可以实现对应的监听器(Listener)。
一、ServletContext事件、监听器
与ServletContext相关的监听器有两个,ServletContextListener、ServletContextAttributeListener
1、ServletContextListener
它是生命周期监听器,如果想要知道何时web应用程序已经初始化或者即将结束销毁,可以实现该监听器。
例如,可以实现ServletContextListener,在此应用程序初始过程中,准备好数据库连接线对象、读取应用程序设置等动作,如放置使用头像的目录信息,就不适合将目录名称写死,这时候可以这么做:
1 package cc.openhome;
2 import javax.servlet.*;
3 @WebListener //使用@weblistener标注
4 public class ContextParameterReader implements ServletContextListener{
5 public void contextInitialized(ServletContextEvent e){
6 ServletContext context = sce.getServletContext();//取得ServletContext
7 String avatars = context.getInitParameter("AVATAR");//取得初始参数
8 context.setAttribute("avatars",avatars);//设置ServletContext属性
9 }
10 public void contextDestroyed(ServletContextEvent sce){}
11 }
整个web应用程序生命周期,Servlet共享的资料可以设置为ServletContext属性。这些属性数据会一直存在于web应用程序中。可以通过setAttribute()方法设置对象为ServletContext属性,之后可通过ServletContext的getAttribute()方法取出该属性。如果移除属性,用removeAttribute()。
1 package ServletAPI; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.annotation.WebInitParam; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 /** 14 * Servlet implementation class Avatar 15 */ 16 @WebServlet( 17 urlPatterns = { "/avatar.view" }, 18 initParams = { 19 @WebInitParam(name = "AVATAR_DIR", value = "/image")//根目录WebContent内部 20 }) 21 public class Avatar extends HttpServlet { 22 private static final long serialVersionUID = 1L; 23 private String AVATAR_DIR; 24 /** 25 * @see HttpServlet#HttpServlet() 26 */ 27 public Avatar() { 28 super(); 29 // TODO Auto-generated constructor stub 30 } 31 public void init() throws ServletException{ 32 //AVATAR_DIR=getInitParameter("AVATAR_DIR"); 33 AVATAR_DIR=(String) getServletContext().getAttribute("avatars"); 34 } 35 36 37 /** 38 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 39 */ 40 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 41 // TODO Auto-generated method stub 42 response.setContentType("text/html;charset=UTF-8"); 43 PrintWriter out=response.getWriter(); 44 out.println("<!DOCTYPE html>"); 45 out.println("<html>"); 46 out.println("<head>"); 47 out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>"); 48 out.println("<title>头像显示</title>"); 49 out.println("</head>"); 50 out.println("<body>"); 51 for(String avatar:getServletContext().getResourcePaths(AVATAR_DIR)){//取得头像路径 52 avatar=avatar.replaceFirst("/", ""); 53 out.println("<img src='"+avatar+"'>"); 54 } 55 out.println("</body>"); 56 out.println("</html>"); 57 out.close(); 58 } 59 60 /** 61 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 62 */ 63 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 64 // TODO Auto-generated method stub 65 } 66 67 }
2、ServletContextAttributeListener
它是监听属性改变的监听器,如果想要对象被设置、移除或替换ServletContext属性,也可以收到通知以进行一些操作,可以实现该监听器。
当在ServletContext中添加属性、移除或者替换属性时,对应的attributeAdded()、attributeRemoved()、attributeReplaced()方法就会被调用。
二、HttpSession事件、监听器
与HttpSession相关的有四个监听器:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener与HttpSessionActivationListener.
1、HttpSessionListener
它是生命周期监听器,如果想要在HttpSession对象创建或者结束时,做些相对应动作,可以实现该监听。
在HttpSession对象初始化或结束之前,会分别调用sessionCreated()、sessionDestroyed()方法,
可以通过传入的HttpSessionEvent,使用getSession()取得HttpSession,以针对会话对象做出相应操作。例如:除非用户注销,否则登录后的用户在另个浏览器上登录会显示登录失败。
如果用户不小心再注销前关闭了浏览器,那么数据库中代表登录与否的字段就不会被重置。为此,可是实现HttpSessionListener,由于HttpSession有存活期限,当容器销毁某个HttpSession时,就会调用sessionDestroyed(),就可以再当中判断要重置哪个用户的数据库中代表登录与否的字段。
例1:显示目前已经在线人数的统计。
1 package ServletAPI; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import javax.servlet.ServletException; 6 import javax.servlet.annotation.WebServlet; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import javax.servlet.http.HttpSession; 11 12 /** 13 * Servlet implementation class Welcome 14 */ 15 @WebServlet("/welcome.view") 16 public class Welcome extends HttpServlet { 17 private static final long serialVersionUID = 1L; 18 19 /** 20 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 21 */ 22 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 23 // TODO Auto-generated method stub 24 response.setContentType("text/html;charset=UTF-8"); 25 PrintWriter out=response.getWriter(); 26 HttpSession session=request.getSession(true); 27 out.println("<html>"); 28 out.println("<head>"); 29 out.println("<title>欢迎</title>"); 30 out.println("</head>"); 31 out.println("<body>"); 32 out.println("<h1>目前在线人数"+OnlineUserCounter.getCounter()+"人</h1>");//获取在线人数 33 if(session!=null){ 34 String user=(String) session.getAttribute("user"); 35 out.println("<h1>欢迎:"+user+"</h1>"); 36 out.println("<a href='logout.do'>注销</a>"); 37 } 38 out.println("</body>"); 39 out.println("</html>"); 40 } 41 42 }
1 package ServletAPI; 2 3 import javax.servlet.annotation.WebListener; 4 5 import javax.servlet.http.HttpSessionEvent; 6 import javax.servlet.http.HttpSessionListener; 7 8 /** 9 * Application Lifecycle Listener implementation class OnlineUserCounter 10 * 11 */ 12 @WebListener() 13 public class OnlineUserCounter implements HttpSessionListener { 14 private static int counter; 15 16 public static int getCounter(){ 17 return counter; 18 } 19 20 /** 21 * @see HttpSessionListener#sessionCreated(HttpSessionEvent) 22 */ 23 public void sessionCreated(HttpSessionEvent se) { 24 // TODO Auto-generated method stub 25 OnlineUserCounter.counter++; 26 } 27 28 /** 29 * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent) 30 */ 31 public void sessionDestroyed(HttpSessionEvent se) { 32 // TODO Auto-generated method stub 33 OnlineUserCounter.counter--; 34 } 35 36 }
1 package ServletAPI; 2 3 import java.io.IOException; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import javax.print.attribute.standard.PagesPerMinute; 8 import javax.servlet.ServletException; 9 import javax.servlet.annotation.WebServlet; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 import org.apache.catalina.User; 15 16 /** 17 * Servlet implementation class loginlistener 18 */ 19 @WebServlet("/listener.view") 20 public class loginlistener extends HttpServlet { 21 private static final long serialVersionUID = 1L; 22 private Map<String, String> users; 23 /** 24 * @see HttpServlet#HttpServlet() 25 */ 26 public loginlistener() { 27 //super(); 28 users=new HashMap<String, String>(); 29 users.put("nihao", "nihaonihao"); 30 users.put("momor", "123456789"); 31 users.put("hamimi", "123456789"); 32 // TODO Auto-generated constructor stub 33 } 34 35 /** 36 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 37 */ 38 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 39 // TODO Auto-generated method stub 40 String name=request.getParameter("user"); 41 String passwd=request.getParameter("passwd"); 42 String page="listenerlogin.html"; 43 if(users.containsKey(name) && users.get(name).equals(passwd)){ 44 User user=(User) new ServletAPI.User(name); 45 request.getSession().setAttribute("user", user); 46 page="welcome.view"; 47 } 48 response.sendRedirect(page); 49 } 50 51 }
运行结果:
2、HttpSessionAttributeListener
它是属性改变监听器,用法同ServletContextAttributeListener一样。
3、HttpSessionBindingListener
它是对象绑定监听器,如果有个即将加HttpSessionBindingListener入HttpSession的属性对象,希望在设置给HttpSession成为属性或从HttpSession中删除时,可以收到HttpSession的通知,可以让该对象实现该监听器。
当实现此接口的属性对象被加入HttpSession或冲中移除,就会调用valueBound()与valueUnbound()方法,并传入HttpSessionBindingEvent对象,可以通过该对象的getSession()取得HttpSession对象。
4、HttpSessionActivationListener
对象迁移监听器,几乎不会用到。
三、HttpServletRequest事件、监听器
有三个相关的监听器:ServletRequestListener、ServletRequestAttributeListener、AsyncListener(这个在异步处理时会介绍到)。