04_02_javaweb Fiter+Listener核心技术

前言

文章内容输出来源:拉勾教育Java就业训练营

Filter+Listener核心技术

Filter过滤器

基本概念

  • Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener。
  • 过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
  • 过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。

工作方式

在这里插入图片描述

使用方式

  • 自定义类实现Filter接口并重写doFilter方法。
public class LoginFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException {
		//TODO 处理逻辑,必须调用下面的方法
		chain.doFilter(request,response); 
	} 
}
  • 在web.xml文件中配置过滤器。
<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.lagou.LoginFilter</filter-class>
</filter> 

<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Filter接口

  1. 基本概念
    javax.servlet.Filter接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作。
  2. 常用方法
方法声明功能介绍
void init(FilterConfig filterConfig)实现过滤器的初始化操作
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)执行过滤操作的功能
void destroy()实现过滤器的销毁操作

示例:调用以上方法来测试生命周期

package com.lagou.demo02;

import javax.servlet.*;
import java.io.IOException;

public class LifeFilter implements Filter {

    public LifeFilter() {
        System.out.println("构造方法执行了");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化操作。。。");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("阻拦一切不和理的访问");
        //放开拦截,使其正常跳转
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
        System.out.println("销毁操作执行完毕了");
    }
}

生命周期的测试:life.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>生命周期的测试</title>
</head>
<body>
<h1>生命周期的测试效果哦!</h1>
</body>
</html>

配置方式:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<filter>
    <filter-name>LifeFilter</filter-name>
    <filter-class>com.lagou.demo02.LifeFilter</filter-class>
</filter>
    <filter-mapping>
        <filter-name>LifeFilter</filter-name>
        <url-pattern>*.html </url-pattern>
    </filter-mapping>
</web-app>

结果:

  1. init()方法会在构造方法被调用后直接被调用初始化。
  2. doFilter()方法会在访问其他页面时进行拦截。
  3. destroy()当重启服务器或者关闭服务器时将会进行销毁。
    备注:如果有构造方法,那么先创建构造方法,在进行初始化。

FilterConfig接口

  1. 基本概念
    javax.servlet.FilterConfig接口主要用于描述过滤器的配置信息。
  2. 常用方法
方法声明功能介绍
String getFilterName()获取过滤器的名字
String getInitParameter(String name)获取指定的初始化参数信息
Enumeration getInitParameterNames()获取所有的初始化操作名称
ServletContext getServletContext()获取ServletContext对象

示例:演示FilterConfig接口的操作
LifeFilter.java;在init()方法中进行

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化操作。。。");
        System.out.println("获取到的过滤器名称为:" + filterConfig.getFilterName());
        String userName = filterConfig.getInitParameter("userName");//admin
        System.out.println("获取到指定初始化数值为:" + userName);
        Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            //userName password
            System.out.println("获取到的初始化的参数名为:" + initParameterNames.nextElement());
        }
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println("获取到的上下文对象是:" + servletContext);
    }

web.xml中配置初始化值:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <filter>
        <filter-name>LifeFilter</filter-name>
        <filter-class>com.lagou.demo02.LifeFilter</filter-class>
        <init-param>
            <param-name>userName</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>123456</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>LifeFilter</filter-name>
        <url-pattern>*.html</url-pattern>
    </filter-mapping>
</web-app>

获取到的结果为:

构造方法执行了
初始化操作。。。
获取到的过滤器名称为:LifeFilter
获取到指定初始化数值为:admin
获取到的初始化的参数名为:password
获取到的初始化的参数名为:userName
获取到的上下文对象是:org.apache.catalina.core

多个过滤器的使用

  • 如果有多个过滤器都满足过滤的条件,则容器依据映射的先后顺序来调用各个过滤器。
    在这里插入图片描述
    示例:构建多道防线测试防线的先后顺序
    第一道过滤器:AFilter.java
import javax.servlet.*;
import java.io.IOException;

public class AFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("这是第一道防线");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("第一道防线返回");
    }
    @Override
    public void destroy() {
    }
}

第二道过滤器:BFilter.java

import javax.servlet.*;
import java.io.IOException;

public class BFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("这是第二道防线");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("第二道防线返回");
    }

    @Override
    public void destroy() {
    }
}

xml配置文件:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>Afilter</filter-name>
        <filter-class>com.lagou.demo02.AFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Afilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Bfilter</filter-name>
        <filter-class>com.lagou.demo02.BFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Bfilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>
</web-app>

过滤器启动的先后顺序是根据<filter-mapping>的先后顺序来进行排序的。

输出结果:

这是第一道防线
这是第二道防线
第二道防线返回
第一道防线返回

过滤器优点

  • 实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
  • 可以将多个相同处理逻辑的模块集中写在过滤器里面,可实现重复利用、也方便代码的维护。

Listener监听器

基本概念

  • Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理。
  • 容器产生的事件分类如下:
    1. 生命周期相关的事件。
    2. 属性状态相关的事件。
    3. 存值状态相关的事件。
  • 底层原理是采用接口回调的方式实现。

基本分类

监听器类型功能介绍
javax.servlet.ServletRequestListener监听request作用域的创建和销毁
javax.servlet.ServletRequestAttributeListener监听request作用域的属性状态变化
javax.servlet.http.HttpSessionListener监听session作用域的创建和销毁
javax.servlet.http.HttpSessionAttributeListener监听session作用域的属性状态变化
javax.servlet.ServletContextListener监听application作用域的创建和销毁
javax.servlet.ServletContextAttributeListener监听application作用域的属性状态变化
javax.servlet.http.HttpSessionBindingListener监听对象与session的绑定和解除
javax.servlet.http.HttpSessionActivationListener监听session数值的钝化和活化

监听器详解

ServletRequestListener监听器
  • 在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。
  • 常用方法如下:
方法声明功能介绍
void requestInitialized(ServletRequestEvent sre)实现ServletRequest对象的初始化
void requestDestroyed(ServletRequestEvent sre)实现ServletRequest对象的销毁

示例:测试监听器的创建和关闭
实现ServletRequestListener的接口:MyRequestListener.java

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求销毁了。。。");
    }
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("创建请求了。。。");
    }
}

xml的配置项:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.lagou.demo03.MyRequestListener</listener-class>
    </listener>
</web-app>

结果:当进入了浏览器进行访问时,会有创建请求了。。。而后会执行请求销毁了。。。
注意:idea的功能强大,他自动启动浏览器时会请求2次,所以如果要进行测试的话将自动启动浏览器关闭。

ServletRequestAttributeListener监听器
  • 向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。
  • 常用方法如下:
方法声明功能介绍
void attributeAdded(ServletRequestAttributeEvent srae)增加属性时触发
void attributeReplaced(ServletRequestAttributeEvent srae)修改属性时触发
void attributeRemoved(ServletRequestAttributeEvent srae)删除属性时触发

测试属性出现的变化,进行监听
实现类型ServletRequestAttributeListener:MyRequestAttributeListener.java

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class MyRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("增加了属性:" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("删除了属性:" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("修改了属性:" + servletRequestAttributeEvent.getName());
    }
}

配置xml文件:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.lagou.demo03.MyRequestAttributeListener</listener-class>
    </listener>
</web-app>
HttpSessionListener监听器
  • 当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。
  • 常用方法如下:
方法声明功能介绍
void sessionCreated(HttpSessionEventse)当一个HttpSession对象被创建时会调用这个方法
void sessionDestroyed(HttpSessionEventse)当一个HttpSession超时或者调用HttpSession的invalidate()方法让它销毁时,将会调用这个方法

示例:测试监听session创建和销毁
实现HttpSessionListener:MySessionListener.java

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

public class MySessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("创建了session");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session销毁");
    }
}

配置xml:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.lagou.demo03.MySessionListener</listener-class>
    </listener>
    <session-config>
        <!--设置session销毁时间-->
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>

结果:当进入页面时就会创建session,等待3分钟后session就会被销毁。

HttpSessionAttributeListener监听器
  • HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。
  • 常用方法如下:
方法声明功能介绍
void attributeAdded(HttpSessionBindingEventse)当往会话中加入一个属性的时候会调用这个方法
void attributeRemoved(HttpSessionBindingEventse)当从会话中删除一个属性的时候会调用这个方法
void attributeReplaced(HttpSessionBindingEvent se)当改变会话中的属性的时候会调用这个方法

示例:测试Session会话的增删改的效果
实现HttpSessionAttributeListener:MySessionAttributeListener.java

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

public class MySessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("增加了属性:" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("删除了属性:" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("修改了属性:" + httpSessionBindingEvent.getName());
    }
}

配置xml:web.xml

    <listener>
        <listener-class>com.lagou.demo03.MySessionAttributeListener</listener-class>
    </listener>

实现会话属性状态的改变操作: sessionAttribute.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现会话中属性状态的改变</title>
</head>
<body>
<%
    //增加属性
    session.setAttribute("name","caocao");
    //修改属性
    session.setAttribute("name","caoren");
    //删除属性
    session.removeAttribute("name");
%>
</body>
</html>

结果:当进入sessionAttribute.jsp界面是,后台打印出

增加了属性:name
修改了属性:name
删除了属性:name
ServletContextListener监听器
  • 在ServletContext创建和关闭时都会通知ServletContextListener监听器。
  • 常用方法如下:
方法声明功能介绍
void contextInitialized(ServletContextEventsce)当ServletContext创建的时候,将会调用这个方法
void contextDestroyed(ServletContextEventsce)当ServletContext销毁的时候(例如关闭应用服务器或者重新加载应用),将会调用这个方法

示例:测试接口ServletContextListener。
实现ServletContextListener接口为:MyServletContextListener.java

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象创建了...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象被销毁了...");
    }
}

配置:web.xml

    <listener>
        <listener-class>com.lagou.demo03.MyServletContextListener</listener-class>
    </listener>

结果:当启动时,ServletContext被创建了,当停止服务器后,ServletContext被销毁了。

ServletContextAttributeListener监听器
  • 向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器
  • 常用方法如下:
方法声明功能介绍
void attributeAdded(ServletContextAttributeEvent scae)往ServletContext中加入一个属性的时候触发
void attributeRemoved(ServletContextAttributeEventscae)从ServletContext中删除一个属性的时候触发
void attributeReplaced(ServletContextAttributeEventscae)改变ServletContext中属性的时候触发

示例:测试ServletContextAttributeListener接口
实现ServletContextAttributeListener接口:MyServletContextAttributeListener.java

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("增加了属性:"+servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("删除了属性:"+servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("修改了属性"+servletContextAttributeEvent.getName());
    }
}

配置:web.xml

        <listener>
            <listener-class>com.lagou.demo03.MyServletContextAttributeListener</listener-class>
        </listener>

测试页面:contextAttribute.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现SerbletContex对象属性的改变</title>
</head>
<body>
<%
    //增加属性
    application.setAttribute("name", "zhaosan");
    //修改属性
    application.setAttribute("name", "lisi");
    //删除属性
    application.removeAttribute("name");
%>
</body>
</html>

结果:当进入页面后

增加了属性:org.apache.jasper.runtime.JspApplicationContextImpl
增加了属性:org.apache.jasper.compiler.ELInterpreter
增加了属性:name
修改了属性name
删除了属性:name
HttpSessionBindingListener监听器
  • HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器。
  • 常用方法如下:
方法声明功能介绍
void valueBound(HttpSessionBindingEvent event)有对象绑定时调用该方法
void valueUnbound(HttpSessionBindingEvent event)有对象解除绑定时调用该方法

示例:监控HttpSession中对象的绑定和解绑效果
实现接口HttpSessionListener的实体类:Person.java

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class Person  implements HttpSessionBindingListener {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("对象绑定到session中了");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("解除绑定成功");
    }
}

测试数据:sessionBind.jsp

<%@ page import="com.lagou.demo03.Person" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现session中对象的绑定和解除</title>
</head>
<body>
<%
    //准备Person对象
    Person person = new Person();
    person.setName("zhangsan");
    person.setAge(30);
    //将对象与session对象进行绑定
    session.setAttribute("person",person);
    //解除绑定
    session.removeAttribute("person");
%>
</body>
</html>

结果:当从页面进入后将会显示出:

对象绑定到session中了
解除绑定成功
HttpSessionActivationListener监听器
  • 当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。
  • 常用方法如下:
方法声明功能介绍
void sessionWillPassivate(HttpSessionEvent se)有钝化操作时调用该方法(序列化操作类似,直接写入到硬盘中)
void sessionDidActivate(HttpSessionEvent se)有活化操作时调用该方法(从硬盘中取出)
  • 配置Tomcat下的conf中的context.xml文件将如下代码复制粘贴:
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true"> 
    <!-- 配置文件存放的路径信息,可以自由指定 -->
    <Store className="org.apache.catalina.session.FileStore" directory="C:\session"/>
</Manager>

示例:进行session中的钝化和活化操作
实体类:Student.java

package com.lagou.demo03;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

public class Student implements Serializable , HttpSessionActivationListener {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }



    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("执行了钝化操作"+httpSessionEvent.getSession());
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("活化操作进行中。。。");
    }
}

进行钝化操作:sessionAcivate.jsp

<%@ page import="com.lagou.demo03.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现session中的数据的钝化和活化操作</title>
</head>
<body>
<%
    //创建Student类型的对象
    Student student = new Student();
    student.setName("zhangsan");
    //将数据放入到session中
    session.setAttribute("student",student);
%>
</body>
</html>

进行活化操作:sessionGet.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现session中数据的获取</title>
</head>
<body>
<%
    Object student = session.getAttribute("student");
    System.out.println("获取到的数据为:"+student);
%>
</body>
</html>

结果:当进入到sessionAcivate.jsp的页面后,将服务器关闭,将会执行钝化操作。
当进入到sessionGet.jsp的页面后,会进行活化操作,将钝化存储的值获取。

实战案例

监听当前的在线用户。
自定义类实现监听器接口并重写相关的方法。

public class OnlineUser implements HttpSessionListener, ServletContextListener {
    ServletContext ctx = null;

    // 初始化ServletContext
    public void contextInitialized(ServletContextEvent e) {
        ctx = e.getServletContext();
    }

    // 销毁ServletContext 
    public void contextDestroyed(ServletContextEvent e) {
        //将ServletContext设置成null; 
    }

    // 当新创建一个HttpSession对象时 
    public void sessionCreated(HttpSessionEvent e) {
        //将当前的在线人数加上1,并且保存到ServletContext(application)中 
    }

    // 当一个HttpSession被销毁时(过期或者调用了invalidate()方法) 
    public void sessionDestroyed(HttpSessionEvent e) {
        //将当前人数减去1,并且保存到ServletContext(application)中 
    }
}
  • 在web.xml中配置监听器
<listener> 
	<listener-class>com.lagou.listener.OnlineUser </listener-class> 
</listener>

示例:
继承对应接口,OnlineUser.java

package com.lagou.demo04;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OnlineUser implements HttpSessionListener, ServletContextListener {
    //声明一个ServletContext类型的引用放在作为全局对象来记录当前在线用户的数量,通过属性记录
    ServletContext servletContext = null;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        servletContext = servletContextEvent.getServletContext();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        servletContext = null;
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("有新用户上线...");
        //若当前用户为第一个用户,则将全局对象中的属性值设置为1即可
        Object count = servletContext.getAttribute("count");
        if (null == count) {
            servletContext.setAttribute("count", 1);
        } else {
            //若当前用户不是第一个用户,则将全局对象中原有的数据取出来加1后在设置上去
            Integer integer = (Integer) count;
            integer++;
            servletContext.setAttribute("count", integer);
        }
        System.out.println("当前在线用户数量为:" + servletContext.getAttribute("count"));
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("有用户已下线");
    }


}

文件配置:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <listener>
        <listener-class>com.lagou.demo04.OnlineUser</listener-class>
    </listener>
</web-app>

显示页面:onlineUser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现当前用户的在线数量</title>
</head>
<body>
<h1>当前在线用户为:${applicationScope.count}</h1>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值