Listener執行流程 – JAVA編程語言程序開發技術文章

每次說起監聽器,總是有些空的感覺,那麼它到底是個什麼東西呢?

一.概念

    監聽器也叫 Listener,是 Servlet的監聽器,它可以監聽客戶端的請求,服務端的操作等。

    監聽器可以自動激發一些操作,比如監聽在線的用戶的數量. 當增加一個 HttpSession時,就激發 sessionCreated(HttpSessionEvent se) 方法,這樣就可以給在線人數加 1。

 

二.執行原理

    其實監聽器的執行類似於觸發器,當某些動作(接口中定義好的)執行時就會觸發(至於到底是如何觸發的就是底層的問題瞭)相應的Listener,執行相應的操作;當然如果沒有執行對應的動作,則監聽器就一直監聽著,沒有操作。

    下面我來舉個例子(監聽在線用戶的數量),來展示一下Listener的執行過程,先來看一下它的時序圖:

 

 

 login.jsp

 

[java] <%@ page language="java" contentType="text/html; charset=GB18030" 
    pageEncoding="GB18030"%> 
<% 
    String command = request.getParameter("command"); 
    if ("login".equals(command)) { 
        if ("dan".equals(request.getParameter("userId")) 
                && "123".equals(request.getParameter("password"))) { 
 
            //登陸成功將用戶信息放到session中  
            session.setAttribute("user_name", 
                    request.getParameter("userId")); 
 
            //設置超時,單位:秒  
            session.setMaxInactiveInterval(6000); 
             
 
            //重定向到主控頁面  
            response.sendRedirect(request.getContextPath() + "/index.jsp"); 
        } 
    } 
%> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=GB18030"> 
<title>登錄</title> 
<SCRIPT language=JavaScript> 
    function init() { 
        loginForm.userId.focus(); 
    } 
 
</SCRIPT> 
</head> 
<body onload=init()> 
    <FORM name="loginForm"> 
        <input type="hidden" name="command" value="login">     
        用戶名:   
        <INPUT name="userId" value="dan" type="text" size="20"   maxlength="20">  
        <p>密   碼:  
        <INPUT name="password"   value="123" type="password" size="21" maxlength="20">  
        <input type="submit" onclick="submitForm()" value="提交" name="login" id="login"> 
    </FORM> 
</body> 
</html> 
<%@ page language="java" contentType="text/html; charset=GB18030"
 pageEncoding="GB18030"%>
<%
 String command = request.getParameter("command");
 if ("login".equals(command)) {
  if ("dan".equals(request.getParameter("userId"))
    && "123".equals(request.getParameter("password"))) {

   //登陸成功將用戶信息放到session中
   session.setAttribute("user_name",
     request.getParameter("userId"));

   //設置超時,單位:秒
   session.setMaxInactiveInterval(6000);
   

   //重定向到主控頁面
   response.sendRedirect(request.getContextPath() + "/index.jsp");
  }
 }
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>登錄</title>
<SCRIPT language=JavaScript>
 function init() {
  loginForm.userId.focus();
 }

</SCRIPT>
</head>
<body onload=init()>
 <FORM name="loginForm">
  <input type="hidden" name="command" value="login"> 
  用戶名: 
  <INPUT name="userId" value="dan" type="text" size="20" maxlength="20">
  <p>密   碼:
  <INPUT name="password" value="123" type="password" size="21" maxlength="20">
  <input type="submit" onclick="submitForm()" value="提交" name="login" id="login">
 </FORM>
</body>
</html>

 

    TestHttpSessionListener.java

 

[java] package listener; 
 
import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 
 
public class TestHttpSessionListener implements HttpSessionListener { 
 
    @Override 
    public void sessionCreated(HttpSessionEvent se) { 
        System.out.println("————-TestHttpSessionListener.sessionCreated———————"); 
    } 
 
    @Override 
    public void sessionDestroyed(HttpSessionEvent arg0) { 
         
    } 
 

package listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class TestHttpSessionListener implements HttpSessionListener {

 @Override
 public void sessionCreated(HttpSessionEvent se) {
  System.out.println("————-TestHttpSessionListener.sessionCreated———————");
 }

 @Override
 public void sessionDestroyed(HttpSessionEvent arg0) {
  
 }

}

 

    TestHttpSessionAttributeListener.java

  

[java] package listener; 
 
import javax.servlet.http.HttpSessionAttributeListener; 
import javax.servlet.http.HttpSessionBindingEvent; 
 
 
public class TestHttpSessionAttributeListener implements 
        HttpSessionAttributeListener { 
 
    @Override 
    public void attributeAdded(HttpSessionBindingEvent se) { 
        System.out.println("name==========" + se.getName()); 
        System.out.println("value==========" + se.getValue()); 
        if ("user_name".equals(se.getName())) { 
            Integer count = (Integer)se.getSession().getServletContext().getAttribute("count"); 
            if (count == null) { 
                count = 1; 
            }else { 
                count++; 
            } 
            se.getSession().getServletContext().setAttribute("count", count); 
        } 
        System.out.println("count=" + se.getSession().getServletContext().getAttribute("count")); 
    } 
 
    @Override 
    public void attributeRemoved(HttpSessionBindingEvent se) { 
        System.out.println("TestHttpSessionAttributeListener===>>>>>attributeRemoved" + se.getSession().getServletContext().getAttribute("count")); 
    } 
 
    @Override 
    public void attributeReplaced(HttpSessionBindingEvent arg0) { 
        System.out.println("TestHttpSessionAttributeListener===>>>>>attributeReplaced"); 
    } 
 

package listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class TestHttpSessionAttributeListener implements
  HttpSessionAttributeListener {

 @Override
 public void attributeAdded(HttpSessionBindingEvent se) {
  System.out.println("name==========" + se.getName());
  System.out.println("value==========" + se.getValue());
  if ("user_name".equals(se.getName())) {
   Integer count = (Integer)se.getSession().getServletContext().getAttribute("count");
   if (count == null) {
    count = 1;
   }else {
    count++;
   }
   se.getSession().getServletContext().setAttribute("count", count);
  }
  System.out.println("count=" + se.getSession().getServletContext().getAttribute("count"));
 }

 @Override
 public void attributeRemoved(HttpSessionBindingEvent se) {
  System.out.println("TestHttpSessionAttributeListener===>>>>>attributeRemoved" + se.getSession().getServletContext().getAttribute("count"));
 }

 @Override
 public void attributeReplaced(HttpSessionBindingEvent arg0) {
  System.out.println("TestHttpSessionAttributeListener===>>>>>attributeReplaced");
 }

}

    代碼寫完後,還需要在Web.xml中進行一下配置:

  

[html] <?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> 
   
  <listener> 
    <listener-class>listener.TestHttpSessionListener</listener-class> 
  </listener> 
   
  <listener> 
    <listener-class>listener.TestHttpSessionAttributeListener</listener-class>  
 </listener> 
 
</web-app> 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
 
  <listener>
   <listener-class>listener.TestHttpSessionListener</listener-class>
  </listener>
 
  <listener>
   <listener-class>listener.TestHttpSessionAttributeListener</listener-class>
 </listener>

</web-app>

     執行結果:

 

    代碼解析:

     1.實現接口

     本例是實現瞭兩個監聽,一個是對Session的監聽(可以沒有),一個是對SessionAttribute的監聽,在這裡將兩者都寫出來,是讓大傢對這兩者進行一下區分(明白Session和SessionAttribute是分開進行監聽的)。

     既然是分開的,所以要實現不同的接口,至於為什麼一定要實現接口,就是因為Web服務器對不同的接口已經進行瞭不同的封裝,所以當你進行不同的操作時才會調用到不同的監聽器上。

     2.attributeAdded(HttpSessionBindingEvent se)

     HttpSessionAttributeListener接口中的每一個方法中都有一個HttpSessionBindingEvent參數,它是一個事件對象,就是因為對於Session的Attribute的操作觸發瞭該事件,所以才能將對session的attribute的操作觸發到響應的方法來。

   

三.常用監聽器

   前面隻是提到瞭兩種監聽器,大傢知道不同的操作對應不同的監聽器,下面我就來為大傢介紹一些常用的監聽器:

    1.ServletContextAttributeListener:監聽對 ServletContext 屬性的操作,比如 增加,刪除,修改屬性.

    2.ServletContextListener監聽 ServletContext.

       當創建 ServletContext 時,激 發 contextInitialized(ServletContextEventsce)方法;當銷毀 ServletContext 時,激發 contextDestroyed(ServletContextEvent sce)方 法.      

    3.HttpSessionListener監聽 HttpSession 的操作.

       當創建一個 Session 時,激發 session Created(HttpSessionEvent se)方法;當銷毀一個Session 時,激 發 sessionDestroyed (HttpSessionEvent se)方法.

    4.HttpSessionAttributeListener 監聽 HttpSession 中的屬性的操作.

        當在 Session 增加一個屬性時,激發 attributeAdded(HttpSessionBindingEvent se)方法;當在 Session 刪除 一個屬性時,激發 attributeRemoved(HttpSessionBindingEvent se)方法; 當在Session 屬性被重新設置時,激發 attributeReplaced(HttpSessionBindingEvent se) 方法.

 摘自 趙丹丹的專欄
 

發佈留言