• springboot 用监听器统计在线人数案例分析


    创建HttpSessionListener 监听器

    先写个HttpSessionListener 监听器。count 是session的数量(人数),session 创建的时候,会触发监听器的sessionCreated 方法,session销毁的时候,会触发监听器的sessionDestroyed 方法。 在监听器中计算完人数count,把他放进servletContext(可以理解为一个仓库,任意请求可以存储和获取里面的属性)

    /**
     * @author fanghui
     */
    @SpringBootApplication
    @MapperScan({"com.izkml.energy.data.mapper"})
    @EnableSwagger2
    @EnableAsync
    @EnableCaching
    @ServletComponentScan //添加这个注解
    public class EnergyDataApplication {
        public static void main(String[] args) {
            SpringApplication.run(EnergyDataApplication.class, args);
        }
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")
                            .allowCredentials(true)
                            .allowedOrigins("*")
                            .allowedMethods("GET", "POST");
                }
            };
        }
    }
    

    controller编码

    接着写一个查询session 数量的controller,我开始的时候是像下面这样写的,是错误的!
    从servletContext 中取出count ,把count返回前端

    @RequestMapping("/count")
        @ResponseBody
        public String count(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
            Object count=httpServletRequest.getServletContext().getAttribute("count");
            return "count : "+count;
        }
    

    这样是错误的,测试你会发现,页面看到count 是null ,因为没有创建session,没有触发监听器的统计方法。于是改一下:

    
    @Controller
    public class IndexController {
        @RequestMapping("/count")
        @ResponseBody
        public String count(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
            HttpSession session = httpServletRequest.getSession();
            Object count=session.getServletContext().getAttribute("count");
            return "count : "+count;
        }
    }
    

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

    改成这样测试,看起来是对的,但是有个问题。一个浏览器对应一个session,你打开2个浏览器,看到count是2 ,是对的。但是你关了一个浏览器,再打开,应该是2不变才对,但是变成3 了,原因是session销毁的方法没有执行,重新打开时,服务器找不到用户原来的session ,重新创建了一个session,于是有3个session了,但是浏览器只有2个,也就是模拟应该是只有2个人在线上。
    有2个方法可以解决这个问题,一个是在关闭网页的时候,前端去调用一个方法把session销毁。另一个更好的方法是,让服务器记得原来那个session,即把原来的sessionId 记录在浏览器,下次打开时,把这个sessionId发送过去,这样服务器就不会重新创建。

    代码修改如下:

    
    @Controller
    public class IndexController {
        @RequestMapping("/count")
        @ResponseBody
        public String number(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
            try{  //把sessionId记录在浏览器
                Cookie c = new Cookie("JSESSIONID", URLEncoder.encode(httpServletRequest.getSession().getId(), "utf-8"));
                c.setPath("/");
                //先设置cookie有效期为2天,不用担心,session不会保存2天
                c.setMaxAge( 48*60 * 60);
                httpServletResponse.addCookie(c);
            }catch (Exception e){
                e.printStackTrace();
            }
     
            HttpSession session = httpServletRequest.getSession();
            Object count=session.getServletContext().getAttribute("count");
            return "count : "+count;
        }
    }
    

    总结:这里只是一个小小的案例分析,后续还会结合不同应用业务场景来进行应用,大家可以在评论区进行评论,动一动你们的鼠标可以关注下,博文会持续分享一些干货

  • 相关阅读:
    【java 自动化测试】TestNg 介绍
    【java 自动化测试】第14章:持续集成
    【java 自动化】15章节:课程总结
    【性能测试】看了一个博客,总结一下
    【Dubbo】Dubbo 接口是什么? 与http 接口有什么区别?
    【jmeter】性能测试报告分析
    Netty 相关目录
    Netty 源码学习——EventLoop
    Netty 源码分析——ChannelPipeline
    Netty 源码学习——服务端流程分析
  • 原文地址:https://www.cnblogs.com/fangh816/p/13489759.html
Copyright © 2020-2023  润新知