Listener的簡單介紹及使用


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> <table> <tr> <td>ID</td> <td>名稱</td> </tr> <% HashMap<String,String> online=(HashMap<String,String>)application.getAttribute("online"); for(String sessionId:online.keySet()){ %> <tr> <td><%=sessionId%></td> <td><%=online.get(sessionId)%></td> </tr> <% } %> </table> </body> </html> 

 

三、使用RequestListener更精確監控用戶在線狀態

1、實現ServletRequestListener package listener; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletContext; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import dao.DbDao; public class RequestListener implements ServletRequestListener,ServletRequestAttributeListener{ //當請求銷毀時觸發該方法 public void requestDestroyed(ServletRequestEvent sre) { // TODO Auto-generated method stub HttpServletRequest request=(HttpServletRequest)sre.getServletRequest(); System.out.println("----發向"+request.getRequestURI()+"被銷毀"); } //當請求初始化時觸發該方法 public void requestInitialized(ServletRequestEvent sre) { // TODO Auto-generated method stub HttpServletRequest request=(HttpServletRequest)sre.getServletRequest(); System.out.println("---發向"+request.getRequestURI()+"被初始化"); HttpSession session=request.getSession(); //獲取sessionId String sessionId=session.getId(); //獲取IP與地址 String ip=request.getRemoteAddr(); //獲取正在訪問的頁面 String page=request.getRequestURI(); //獲取用戶名稱 String user=(String)session.getAttribute("user"); user=(user==null)?"游客":user; DbDao db=new DbDao("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/escshop", "root", ""); ResultSet rs=db.query("SELECT * FROM online_information WHERE sessionId=?", true, sessionId); try { if(rs.next()) { rs.updateString(4, page); rs.updateString(5,String.valueOf(System.currentTimeMillis())); rs.updateRow(); rs.close(); }else{ db.insert(sessionId, user, ip, page, String.valueOf(System.currentTimeMillis())); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //當新增屬性時觸發該方法 public void attributeAdded(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub ServletContext request=srae.getServletContext(); String name=srae.getName(); Object value=srae.getValue(); System.out.println(request+"范圍內新增了屬性名為name="+name+"\t"+"屬性值為value="+value); } //當移除屬性時觸發該方法 public void attributeRemoved(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub ServletContext request=srae.getServletContext(); String name=srae.getName(); Object value=srae.getValue(); System.out.println(request+"范圍內移除了屬性名為name="+name+"\t"+"屬性值為value="+value); } //當替換屬性時觸發該方法 public void attributeReplaced(ServletRequestAttributeEvent srae) { // TODO Auto-generated method stub ServletContext request=srae.getServletContext(); String name=srae.getName(); Object value=srae.getValue(); System.out.println(request+"范圍內替換了屬性名為name="+name+"\t"+"屬性值為value="+value); } } 2、實現ServletContextListener監聽器 package listener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.swing.Timer; import dao.DbDao; public class OnlineRequestListener implements ServletContextListener{ //超過10分鍾沒訪問則判斷已經離線 public final int MAX_MILLITS=10*60*1000; //應用銷毀時執行此方法 public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } //應用啟動時執行此方法 public void contextInitialized(ServletContextEvent arg0) { // TODO Auto-generated method stub //每5秒檢查一次啊 new Timer(1000*5, new ActionListener() { public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub DbDao db=new DbDao("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/escshop", "root", ""); ResultSet rs=db.query("SELECT * FROM online_information"); StringBuffer buff=new StringBuffer("("); try { while (rs.next()) { //如果距離時間超過上次訪問時間 if(System.currentTimeMillis()-Long.parseLong(rs.getString("time"))>MAX_MILLITS){ buff.append("'"); buff.append(rs.getString(1)); buff.append("' ,"); } } System.out.println("buff:"+buff); //有刪除的記錄 if(buff.length()>3){ buff.setLength(buff.length()-3); buff.append("')"); //刪除所有在指定時間內未訪問的用戶信息 String sql="delete from online_information where sessionId in"+buff.toString(); System.out.println("sql:"+sql); db.delete(sql); } } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }).start(); } } 3、數據庫操作 package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DbDao { private String driver; private String url; private String user; private String password; //構造方法 public DbDao(String driver,String url,String user,String password){ this.driver=driver; this.url=url; this.user=user; this.password=password; } //查詢指定ID信息 public ResultSet query(String sql,boolean flag,String id){ ResultSet rs=null; try { Class.forName(driver); try { Connection conn=DriverManager.getConnection(url, user, password); Statement smt=conn.createStatement(); if(flag){ sql=sql.replace("?","'"+id+"'"); } rs=smt.executeQuery(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rs; } //查詢所有信息 public ResultSet query(String sql){ ResultSet rs=null; try { Class.forName(driver); try { Connection conn=DriverManager.getConnection(url, user, password); Statement smt=conn.createStatement(); rs=smt.executeQuery(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rs; } //插入信息 public boolean insert(String sessionId,String userName,String ip,String page,String time){ boolean flag=false; try { Class.forName(driver); try { Connection conn=DriverManager.getConnection(url, user,password); Statement smt=conn.createStatement(); String sql="INSERT INTO online_information(sessionId,USER,ip,page,TIME)" +"VALUES('"+sessionId+"','"+userName+"','"+ip+"','"+page+"','"+time+"')"; System.out.println("SQL:"+sql); flag=smt.executeUpdate(sql)>0?true:false; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return flag; } //刪除指定的目錄 public boolean delete(String sql){ boolean flag=false; try { Class.forName(driver); try { Connection conn=DriverManager.getConnection(url, user,password); Statement smt=conn.createStatement(); flag=smt.executeUpdate(sql)>0?true:false; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return flag; } } 4、顯示在線人員狀態的JSP <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@page import="dao.DbDao"%> <%@page import="java.sql.ResultSet"%> <% 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>online在線人數</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> <h1>當前在線人員:</h1> <table> <% DbDao db=new DbDao("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/escshop", "root", ""); ResultSet rs= db.query("SELECT * FROM online_information"); while(rs.next()){ %> <tr> <td><%=rs.getString(1)%></td> <td><%=rs.getString(2)%></td> <td><%=rs.getString(3)%></td> <td><%=rs.getString(4)%></td> <td><%=rs.getString(5)%></td> </tr> <%} %> </table> </body> </html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM