文章目录
- 监听器使用
- 监听器类型
- ServletContextListener
- HttpSessionListener
- ServletRequestListener
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- HttpSessionBindingListener
监听器(Listener)组件用于监听特定事件的发生,并在事件触发时执行相应的处理逻辑。监听器主要基于Java的观察者模式实现,可以用来监控应用程序的生命周期事件,如请求、会话和属性的变化等。
监听器使用
监听器通常在 web.xml
配置文件中进行注册,也可以使用注解的方式。
<listener><listener-class>com.example.MyContextListener</listener-class>
</listener>
使用注解配置(需要Servlet 3.0及以上)
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;@WebListener
public class MyContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {// 应用启动时执行的代码}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 应用关闭时执行的代码}
}
监听器类型
监听三个域对象的创建和销毁事件的监听器:ServletContextListener
、HttpSessionListener
和 ServletRequestListener
监听域对象中属性的增加、删除、替换事件的监听器:ServletContextAttributeListener
、HttpSessionAttributeListener
和 ServletRequestAttributeListener
监听绑定到 HttpSession
域中的某个对象的状态的监听器,又称为感知型监听器:HttpSessionBindingListener
ServletContextListener
用于监听ServletContext的创建和销毁事件。当Web应用启动或关闭时,可以执行初始化和清理工作。
public interface ServletContextListener extends EventListener {// 当Web应用启动时调用void contextInitialized(ServletContextEvent sce);// 当Web应用关闭时调用void contextDestroyed(ServletContextEvent sce);
}
HttpSessionListener
用于监听HTTP会话的创建和销毁事件。可以在用户登录或注销时进行相应的处理,比如记录在线用户数量。
public interface HttpSessionListener extends EventListener {// 当一个新的HttpSession被创建时调用void sessionCreated(HttpSessionEvent se);// 当一个HttpSession被销毁时调用void sessionDestroyed(HttpSessionEvent se);
}
ServletRequestListener
用于监听Servlet请求的创建和销毁事件。可以在请求处理的开始和结束时执行一些操作,比如记录日志。
public interface ServletRequestListener extends EventListener {// 当一个请求被初始化时调用void requestInitialized(ServletRequestEvent sre);// 当一个请求结束时调用void requestDestroyed(ServletRequestEvent sre);
}
ServletContextAttributeListener
用于监听ServletContext属性的添加、移除和替换。
public interface ServletContextAttributeListener extends EventListener {// 当一个属性被添加到ServletContext时调用void attributeAdded(ServletContextAttributeEvent scae);// 当一个属性从ServletContext中移除时调用void attributeRemoved(ServletContextAttributeEvent scae);//当一个属性在ServletContext中被替换时调用void attributeReplaced(ServletContextAttributeEvent scae);
}
HttpSessionAttributeListener
用于监听会话属性的添加、修改和移除事件。适合在会话中添加或删除属性时进行处理。
public interface HttpSessionAttributeListener extends EventListener {// 当一个属性被添加到HttpSession时调用void attributeAdded(HttpSessionBindingEvent se);// 当一个属性从HttpSession中移除时调用void attributeRemoved(HttpSessionBindingEvent se);// 当一个属性在HttpSession中被替换时调用void attributeReplaced(HttpSessionBindingEvent se)
}
ServletRequestAttributeListener
用于监听请求属性的变化,适合监控请求数据的添加或修改。
public interface ServletRequestAttributeListener extends EventListener {// 当一个属性被添加到ServletRequest时调用void attributeAdded(ServletRequestAttributeEvent srae);// 当一个属性从ServletRequest中移除时调用void attributeRemoved(ServletRequestAttributeEvent srae);// 当一个属性在ServletRequest中被替换时调用void attributeReplaced(ServletRequestAttributeEvent srae);
}
使用监听器统计在线人数
HttpSessionBindingListener
接口定义
public interface HttpSessionBindingListener extends EventListener {void valueBound(HttpSessionBindingEvent event);void valueUnbound(HttpSessionBindingEvent event);
}
创建一个类实现 HttpSessionBindingListener
接口。valueBound
和 valueUnbound
方法分别在对象绑定到会话和从会话中解除绑定时调用
public class OnlineUserCounter implements HttpSessionBindingListener {private static int onlineCount = 0;@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 用户登录时增加在线用户数synchronized (OnlineUserCounter.class) {onlineCount++;}System.out.println("用户登录,当前在线人数: " + onlineCount);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 用户登出或会话过期时减少在线用户数synchronized (OnlineUserCounter.class) {if (onlineCount > 0) {onlineCount--;}}System.out.println("用户登出,当前在线人数: " + onlineCount);}public static int getOnlineCount() {return onlineCount;}
}
创建一个Servlet类来处理登录请求,并在登录成功时将 OnlineUserCounter
实例添加到会话中
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");// 假设验证逻辑if ("admin".equals(username) && "123456".equals(password)) {HttpSession session = request.getSession();OnlineUserCounter counter = new OnlineUserCounter();session.setAttribute("user", username); // 设置用户名session.setAttribute("counter", counter); // 绑定计数器// 重定向到欢迎页面response.sendRedirect("welcome.jsp");} else {// 重定向到登录页面,并携带错误信息response.sendRedirect("login.jsp?error=true");}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
创建一个Servlet类来处理登出请求,并使会话失效
public class LogoutServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession(false);if (session != null) {session.invalidate(); // 使会话失效}response.sendRedirect("login.jsp");}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}}
在 web.xml
文件中配置 LoginServlet
、LogoutServlet
以及在线用户统计监听器
<!-- 配置LoginServlet -->
<servlet><servlet-name>LoginServlet</servlet-name><servlet-class>com.hz.LoginServlet</servlet-class>
</servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/login</url-pattern>
</servlet-mapping><!-- 配置LogoutServlet -->
<servlet><servlet-name>LogoutServlet</servlet-name><servlet-class>com.hz.LogoutServlet</servlet-class>
</servlet><servlet-mapping><servlet-name>LogoutServlet</servlet-name><url-pattern>/logout</url-pattern>
</servlet-mapping>
创建登录页面
<div align="center"><form action="login" method="post"><table><tr><td>账号 : </td><td><input type="text" name="username" required></td></tr><tr><td>密码 : </td><td><input type="password" name="password" required></td></tr><tr><td colspan="2" align="center"><input type="submit" value="登录"></td></tr></table></form>
</div>
创建欢迎页面,显示当前在线用户数
<h1>欢迎您, <%= session.getAttribute("user") %>!</h1>
<p>当前在线人数: <%= com.hz.OnlineUserCounter.getOnlineCount() %></p>
<form action="logout" method="post"><input type="submit" value="退出">
</form>
HttpSessionListener
<!-- 配置在线用户统计监听器 -->
<listener><listener-class>com.hz.OnlineUserCounter</listener-class>
</listener>
两者对比
HttpSessionListener
用于会话生命周期管理(用于监听会话的创建和销毁事件)和全局监听(设置一次即可监听整个应用中的所有会话)。
当一个新的会话被创建时,sessionCreated
方法会被调用;当一个会话被销毁时(例如,调用 session.invalidate()
或会话超时),sessionDestroyed
方法会被调用。
- HttpSessionListener 用于监听会话的创建和销毁事件,适用于全局的会话管理。
- HttpSessionListener 只需要设置到web.xml就可以监听整个应用中的所有session
HttpSessionBindingListener
用于对象绑定和解绑事件(监听对象被绑定到会话或从会话中解绑的事件)和局部监听(必须实例化后放入某一个会话中,才能监听该会话中的对象绑定和解绑事件)。
当一个实现了 HttpSessionBindingListener
接口的对象被绑定到会话时,valueBound
方法会被调用;当一个实现了 HttpSessionBindingListener
接口的对象从会话中解绑时(例如,调用 session.removeAttribute()
或会话销毁),valueUnbound
方法会被调用。
- HttpSessionBindingListener 用于监听特定对象被绑定到会话或从会话中解绑的事件,适用于对象级别的生命周期管理。
- HttpSessionBindingListener 必须实例化后放入某一个session中,才能监听