Listener的簡單介紹及使用
一、Listener概述
Listener可以監聽容器中某一執行動作,並根據其要求做出相應的響應。
常用的Web事件的監聽接口如下:
ServletContextListener:用於監聽Web的啟動及關閉
ServletContextAttributeListener:用於監聽ServletContext范圍內屬性的改變
ServletRequestListener:用於監聽用戶請求
ServletRequestAttributeListener:用於監聽ServletRequest范圍屬性的改變
HttpSessionListener:用於監聽用戶session的開始及結束
HttpSessionAttributeListener:用於監聽HttpSession范圍內的屬性改變
二、ServletContextListener的使用
1、配置web.xml(下面例子都使用此配置文件)
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 初始化參數 --> <context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/escshop</param-value> </context-param> <context-param> <param-name>user</param-name> <param-value>root</param-value> </context-param> <context-param> <param-name>pass</param-name> <param-value></param-value> </context-param> <!-- 定義Filter --> <filter> <filter-name>logFilter</filter-name> <filter-class>Filter.LogFilter</filter-class> </filter> <!-- 定義Filter攔截的URL地址 --> <filter-mapping> <filter-name>logFilter</filter-name> <!-- 負責攔截的URL,/*表示攔截所有的請求 --> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 定義AuthorityFilter --> <filter> <filter-name>authority</filter-name> <filter-class>Filter.AuthorityFilter</filter-class> <init-param> <param-name>encode</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>indexPage</param-name> <param-value>/index.jsp</param-value> </init-param> <init-param> <param-name>shopPage</param-name> <param-value>/shop.jsp</param-value> </init-param> </filter> <filter-mapping> <filter-name>authority</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 登錄servlet --> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>Login.LoginServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <!-- 配置監聽Web啟動與關閉的Listener --> <listener> <listener-class>listener.GetConnListener</listener-class> </listener> <!-- 用於監聽ServletContenxt(application)范圍的變化 --> <listener> <listener-class>listener.MyServletContenxtAttributeListener</listener-class> </listener> <!-- 用於監聽用戶請求到達 --> <listener> <listener-class>listener.RequestListener</listener-class> </listener> <listener> <listener-class>listener.OnlineRequestListener</listener-class> </listener> <!--用戶監聽用戶session創建與銷毀 --> <listener> <listener-class>listener.OnlineListener</listener-class> </listener> </web-app>
2、使用ServletContextListener
package listener; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; /** * 監聽Web應用啟動及關閉 * @author xieyongxue * */ public class GetConnListener implements ServletContextListener{ //應用關閉時,此方法被調用 public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub ServletContext application=sce.getServletContext(); Connection conn=(Connection) application.getAttribute("conn"); if (conn!=null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //應用啟動時,此方法被調用 public void contextInitialized(ServletContextEvent sce) { // TODO Auto-generated method stub //獲取到該應用的ServletContext的實例 ServletContext application=sce.getServletContext(); //獲取數據庫驅動 String driver=application.getInitParameter("driver"); //加載數據庫連接URL String url=application.getInitParameter("url"); //獲取登錄數據庫的名稱 String user=application.getInitParameter("user"); //獲取連接數據庫的密碼 String pass=application.getInitParameter("pass"); try { try { Class.forName(driver); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block System.out.println("加載數據庫驅動失敗!"+e.toString()); e.printStackTrace(); } Connection conn= DriverManager.getConnection(url, user, pass); //將數據庫連接設置成application的屬性 application.setAttribute("conn", conn); } catch (SQLException e) { // TODO Auto-generated catch block System.out.println("連接數據庫失敗!"+e.toString()); e.printStackTrace(); } } }
3、使用ServletContextAttributeListener
package listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; public class MyServletContenxtAttributeListener implements ServletContextAttributeListener{ //當程序向application范圍新增屬性時觸發此方法 public void attributeAdded(ServletContextAttributeEvent scab) { // TODO Auto-generated method stub ServletContext application=scab.getServletContext(); //獲取新增的屬性名與值 String name=scab.getName(); Object value=scab.getValue(); System.out.println(application+"范圍內新增了name值為="+name+"value值="+value); } //當程序向application范圍移除屬性時觸發此方法 public void attributeRemoved(ServletContextAttributeEvent scab) { // TODO Auto-generated method stub ServletContext application=scab.getServletContext(); //獲取移除的屬性名與值 String name=scab.getName(); Object value=scab.getValue(); System.out.println(application+"范圍內移除了name值為="+name+"value值="+value); } //當程序向application范圍替換屬性時觸發此方法 public void attributeReplaced(ServletContextAttributeEvent scab) { // TODO Auto-generated method stub ServletContext application=scab.getServletContext(); //獲取替換的屬性名與值 String name=scab.getName(); Object value=scab.getValue(); System.out.println(application+"范圍內替換了name值為="+name+"value值="+value); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
4、測試例子
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; application.setAttribute("addAttrName","addAttrValue"); application.removeAttribute("addAttrName"); application.setAttribute("newAttrName","newAttrValue"); application.setAttribute("newAttrName","1234567"); request.setAttribute("requestName1","requestValue1"); request.removeAttribute("requestName1"); request.setAttribute("requestName2","requestValue2"); request.setAttribute("requestName2","requestValue23"); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>Login</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> ${tip}<br> <form action="login?action=service" method="post"> 名稱:<input type="text" name="user"><br> 密碼:<input type="text" name="pass"><br/> <input type="submit" value="登錄"><input type="reset" value="重置"> </form> </body> </html>
二、使用HttpSessionListener統計用戶在線人數
1、實現HttpSessionListener監聽器
package listener;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineListener implements HttpSessionListener{
//當用戶與服務器開始session時觸發該方法
public void sessionCreated(HttpSessionEvent se) {
// TODO Auto-generated method stub
HttpSession session=se.getSession();
ServletContext application=session.getServletContext();
//獲取sessionId
String sessionId=session.getId();
session.setMaxInactiveInterval(15);
//如果是新連接
if(session.isNew()){
Map<String,String> online=(Map<String, String>) application.getAttribute("online"); String user=(String) session.getAttribute("user"); user=(user==null?"游客":user); if(online==null){ online=new HashMap<String, String>(); } online.put(sessionId, user); application.setAttribute("online", online); } } //當用戶與服務器斷開session時觸發該方法 public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub HttpSession session=se.getSession(); ServletContext application=session.getServletContext(); String sessionId=session.getId(); System.out.println("sessionId:"+sessionId); HashMap<String,String> online=(HashMap<String, String>) application.getAttribute("online"); if(online!=null){ online.remove(sessionId); } application.setAttribute("online",online); } } 2、登錄控制器 package Login; import java.io.IOException; import java.util.HashMap; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; public class LoginServlet extends HttpServlet{ public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ String user=request.getParameter("user"); String pass=request.getParameter("pass"); HttpSession session=request.getSession(); //session.setMaxInactiveInterval(3); session.setAttribute("user", user); session.setAttribute("pass", pass); ServletContext application=session.getServletContext(); HashMap<String,String> dataMap=(HashMap<String, String>) application.getAttribute("online"); if(dataMap==null){ dataMap=new HashMap<String, String>(); } dataMap.put(session.getId(),user); application.setAttribute("online", dataMap); try { //轉發 //request.getRequestDispatcher("/shop.jsp").forward(request, response); //重定向 System.out.println("user1:"+session.getAttribute("user")); response.sendRedirect("/webPrj/shop.jsp"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 3、登錄界面 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; application.setAttribute("addAttrName","addAttrValue"); application.removeAttribute("addAttrName"); application.setAttribute("newAttrName","newAttrValue"); application.setAttribute("newAttrName","1234567"); request.setAttribute("requestName1","requestValue1"); request.removeAttribute("requestName1"); request.setAttribute("requestName2","requestValue2"); request.setAttribute("requestName2","requestValue23"); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>Login</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> ${tip}<br> <form action="login?action=service" method="post"> 名稱:<input type="text" name="user"><br> 密碼:<input type="text" name="pass"><br/> <input type="submit" value="登錄"><input type="reset" value="重置"> </form> </body> </html> 4、在線用戶顯示 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'shop.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="buy.jsp"> 書籍:<input type="checkbox" name="item" value="book"> 電腦:<input type="checkbox" name="item" value="computer"> 汽車:<input type="checkbox" name="item" value="car"> <input type="submit" value="提交"> </form> <h1>在線用戶:</h1> <