自学内容网 自学内容网

【Java Web】监听器类型及其使用


监听器(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 {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 应用启动时执行的代码
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 应用关闭时执行的代码
    }
}

监听器类型

监听三个域对象的创建和销毁事件的监听器:ServletContextListenerHttpSessionListenerServletRequestListener

监听域对象中属性的增加、删除、替换事件的监听器:ServletContextAttributeListenerHttpSessionAttributeListenerServletRequestAttributeListener

监听绑定到 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 接口。valueBoundvalueUnbound 方法分别在对象绑定到会话和从会话中解除绑定时调用

public class OnlineUserCounter implements HttpSessionBindingListener {
    private static int onlineCount = 0;

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        // 用户登录时增加在线用户数
        synchronized (OnlineUserCounter.class) {
            onlineCount++;
        }
        System.out.println("用户登录,当前在线人数: " + onlineCount);
    }

    @Override
    public 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 文件中配置 LoginServletLogoutServlet 以及在线用户统计监听器

<!-- 配置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中,才能监听

原文地址:https://blog.csdn.net/m0_66584716/article/details/143774668

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!