每次說起監聽器,總是有些空的感覺,那麼它到底是個什麼東西呢?
一.概念
監聽器也叫 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) 方法.
摘自 趙丹丹的專欄