Spring Boot HttpSessionListener 监听使用

Posted 早起的年轻人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot HttpSessionListener 监听使用相关的知识,希望对你有一定的参考价值。

监听器通常用于监听 Web 应用程序中对象的创建、销毁等动作的发送,同时对监听的情况作出相应的处理,最常用于统计网站的在线人数、访问量等。

监听器大概分为以下几种:

  • ServletContextListener:用来监听 ServletContext 属性的操作,比如新增、修改、删除。
  • HttpSessionListener:用来监听 Web 应用种的 Session 对象,通常用于统计在线情况。
  • ServletRequestListener:用来监听 Request 对象的属性操作。

通过 HttpSessionListener来统计当前在线人数、ip等信息,为了避免并发问题我们使用原子int来计数。

import lombok.extern.slf4j.Slf4j;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.concurrent.atomic.AtomicInteger;

@WebListener
@Slf4j
public class CustomHttpSessionListener implements HttpSessionListener 
    public static AtomicInteger activeCount = new AtomicInteger(0);


    @Override
    public void sessionCreated(HttpSessionEvent sessionEvent) 

        log.info("-------Incrementing Session Counter--------");
        activeCount.incrementAndGet();
        log.info("-------Session Created--------");
        sessionEvent.getSession().setAttribute("onlineCount", activeCount.get());
        log.info("【在线人数】人数增加为:", activeCount.get());
    

    @Override
    public void sessionDestroyed(HttpSessionEvent sessionEvent) 
        log.info("-------Session Destroyed--------");
        activeCount.getAndDecrement();
        sessionEvent.getSession().getServletContext().setAttribute("sessionCount", activeCount.get());
        log.info("【在线人数】人数减少为:", activeCount.get());

    

或者使用 @Configuration + @Bean 的组合来创建:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class WebCommoneConfig 
    @Bean
    public HttpSessionListener httpSessionListener() 
        return new HttpSessionListener() 
            @Override
            public void sessionCreated(HttpSessionEvent se) 
                System.out.println("Session Created with session id+" + se.getSession().getId());
            

            @Override
            public void sessionDestroyed(HttpSessionEvent se) 
                System.out.println("Session Destroyed, Session id:" + se.getSession().getId());
            
        ;
    


创建 controller 控制器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


@RestController
@RequestMapping("/admin")
public class AdminSessionController 
    @GetMapping("addSession")
    public String addSession(HttpServletRequest request) 
        HttpSession session = request.getSession();
        session.setAttribute("name", "haixiang");
        return "当前在线人数" + session.getServletContext().getAttribute("onlineCount") + "人";
    

    @GetMapping("removeSession")
    public String removeSession(HttpServletRequest request) 
        HttpSession session = request.getSession();
        session.invalidate();
        return "当前在线人数" + session.getServletContext().getAttribute("onlineCount") + "人";
    

    @GetMapping("online")
    public String online() 
        return "当前在线人数" + CustomHttpSessionListener.activeCount.get() + "人";
    


HttpSession session = httpServletRequest.getSession(); 作用:该用户如果没有sesision则创建session ,有则取得session不创建。

一个浏览器对应一个session,你打开2个浏览器,看到count是2 ,是对的。但是你关了一个浏览器,再打开,应该是2不变才对,但是变成3 了,原因是session销毁的方法没有执行,重新打开时,服务器找不到用户原来的session ,重新创建了一个session,于是有3个session了,但是浏览器只有2个,也就是模拟应该是只有2个人在线上。

以上是关于Spring Boot HttpSessionListener 监听使用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring Boot:Spring Boot启动原理分析

Spring Boot:Spring Boot启动原理分析