監聽器類型對照
| 監聽介面 | 監聽事件 |
| ServletContextListener | Context 初始化/銷毀 |
| ServletContextAttributeListener | Context 屬性增/刪/改 |
| HttpSessionListener | Session 建立/銷毀 |
| HttpSessionAttributeListener | Session 屬性增/刪/改 |
1. 監聽 ServletContext (應用層)
public final class MyServletContextListener
implements ServletContextListener, ServletContextAttributeListener {
private ServletContext context = null;
@Override
public void contextInitialized(ServletContextEvent sce) {
this.context = sce.getServletContext();
log("ServletContext 初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log("ServletContext 銷毀");
this.context = null;
}
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
log("Context 新增屬性: " + scae.getName() + "=" + scae.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
log("Context 移除屬性: " + scae.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
log("Context 替換屬性: " + scae.getName() + "=" + scae.getValue());
}
private void log(String msg) {
try (PrintWriter out = new PrintWriter(new FileOutputStream("E:\\contextLog.txt", true))) {
out.println(new Date() + " --> " + msg);
} catch (Exception e) { e.printStackTrace(); }
}
}
2. 監聽 HttpSession (會話層)
public final class MySessionListener
implements HttpSessionListener, HttpSessionAttributeListener {
private ServletContext context;
private int userCount = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
userCount++;
log("Session 建立: " + se.getSession().getId() + ",當前用戶數: " + userCount);
context.setAttribute("users", userCount);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
userCount--;
log("Session 銷毀: " + se.getSession().getId() + ",當前用戶數: " + userCount);
context.setAttribute("users", userCount);
}
@Override
public void attributeAdded(HttpSessionBindingEvent e) {
log("Session 新增屬性: " + e.getName() + "=" + e.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent e) {
log("Session 移除屬性: " + e.getName());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent e) {
log("Session 替換屬性: " + e.getName() + "=" + e.getValue());
}
// Context 監聽 (可選,用於獲取 ServletContext)
@Override
public void contextInitialized(ServletContextEvent sce) {
this.context = sce.getServletContext();
log("ServletContext 初始化 (從 Session 監聽器)");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log("ServletContext 銷毀");
this.context = null;
}
private void log(String msg) {
try (PrintWriter out = new PrintWriter(new FileOutputStream("E:\\sessionLog.txt", true))) {
out.println(new Date() + " --> " + msg);
} catch (Exception e) { e.printStackTrace(); }
}
}
3. 前端 JSP 測試頁
context_test.jsp - 測試 Context 屬性操作
<%@ page contentType="text/html;charset=UTF-8"%>
<%
out.println("新增屬性");
getServletContext().setAttribute("userName", "Smith");
out.println("替換屬性");
getServletContext().setAttribute("userName", "Kate");
out.println("移除屬性");
getServletContext().removeAttribute("userName");
%>
session_test.jsp - 測試 Session 屬性與用戶計數
<%@ page contentType="text/html;charset=UTF-8"%>
執行操作:
session.setAttribute("userName","Smith")<br>
<% session.setAttribute("userName","Smith"); %>
session.setAttribute("userName","Kate")<br>
<% session.setAttribute("userName","Kate"); %>
session.removeAttribute("userName")<br>
<% session.removeAttribute("userName"); %>
目前有 <%=getServletContext().getAttribute("users")%> 個用戶。<br>
銷毀 Session <br>
<% session.invalidate(); %>
目前有 <%=getServletContext().getAttribute("users")%> 個用戶。
4. web.xml 註冊 (Servlet 3.0+ 可用 @WebListener 替代)
<listener>
<listener-class>com.examp.ch9.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>com.examp.ch9.MySessionListener</listener-class>
</listener>