session失效后怎么获取getattribute_监听器应用【统计网站人数、自定义session扫描器、踢人小案例】(修订版)...

news/2024/5/20 14:17:01/文章来源:https://blog.csdn.net/weixin_42205405/article/details/113317283

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

从第一篇已经讲解过了监听器的基本概念,以及Servlet各种的监听器。这篇博文主要讲解的是监听器的应用。

统计网站在线人数

ps:这个可以使用WebSocket来做,但这里讲解的是监听器,所以这里以监听器来举例子!

分析

我们在网站中一般使用Session来标识某用户是否登陆了,如果登陆了,就在Session域中保存相对应的属性。如果没有登陆,那么Session的属性就应该为空。

现在,我们想要统计的是网站的在线人数。我们应该这样做:我们监听是否有新的Session创建了,如果新创建了Sesssion,那么在线人数就应该+1。这个在线人数是整个站点的,所以应该有Context对象保存。

大致思路:

  • 监听Session是否被创建了

  • 如果Session被创建了,那么在Context的域对象的值就应该+1

  • 如果Session从内存中移除了,那么在Context的域对象的值就应该-1.

代码

  • 监听器代码:

public class CountOnline implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent se) {

        //获取得到Context对象,使用Context域对象保存用户在线的个数
        ServletContext context = se.getSession().getServletContext();

        //直接判断Context对象是否存在这个域,如果存在就人数+1,如果不存在,那么就将属性设置到Context域中
        Integer num = (Integer) context.getAttribute("num");

        if (num == null) {
            context.setAttribute("num", 1);
        } else {
            num++;
            context.setAttribute("num", num);
        }
    }
    public void sessionDestroyed(HttpSessionEvent se) {

        ServletContext context = se.getSession().getServletContext();
        Integer num = (Integer) se.getSession().getAttribute("num");

        if (num == null) {
            context.setAttribute("num", 1);
        } else {
            num--;
            context.setAttribute("num", num);
        }
    }
}
  • 显示页面代码:

在线人数:${num}

测试

我们每使用一个浏览器访问服务器,都会新创建一个Session。那么网站的在线人数就会+1。

使用同一个页面刷新,还是使用的是那个Sesssion,所以网站的在线人数是不会变的。

8e4e94b9397e47dbf0cbcab569648007.gif


自定义Session扫描器

我们都知道Session是保存在内存中的,如果Session过多,服务器的压力就会非常大。

但是呢,Session的默认失效时间是30分钟(30分钟没人用才会失效),这造成Seesion可能会过多(没人用也存在内存中,这不是明显浪费吗?)

当然啦,我们可以在web.xml文件中配置Session的生命周期。但是呢,这是由服务器来做的,我嫌它的时间不够准确。(有时候我配置了3分钟,它用4分钟才帮我移除掉Session)

所以,我决定自己用程序手工移除那些长时间没人用的Session。

分析

要想移除长时间没人用的Session,肯定要先拿到全部的Session啦。所以我们使用一个容器来装载站点所有的Session。。

只要Sesssion一创建了,就把Session添加到容器里边。毫无疑问的,我们需要监听Session了。

接着,我们要做的就是隔一段时间就去扫描一下全部Session,如果有Session长时间没使用了,我们就把它从内存中移除。隔一段时间去做某事,这肯定是定时器的任务呀。

定时器应该在服务器一启动的时候,就应该被创建了。因此还需要监听Context

最后,我们还要考虑到并发的问题,如果有人同时访问站点,那么监听Session创建的方法就会被并发访问了定时器扫描容器的时候,可能是获取不到所有的Session的

这需要我们做同步

于是乎,我们已经有大致的思路了

  • 监听Session和Context的创建

  • 使用一个容器来装载Session

  • 定时去扫描Session,如果它长时间没有使用到了,就把该Session从内存中移除。

  • 并发访问的问题


代码

  • 监听器代码:

public class Listener1 implements ServletContextListener,HttpSessionListener {



    //服务器一启动,就应该创建容器。我们使用的是LinkList(涉及到增删)。容器也应该是线程安全的。
    List list = Collections.synchronizedList(new LinkedList());//定义一把锁(Session添加到容器和扫描容器这两个操作应该同步起来)private Object lock = 1;public void contextInitialized(ServletContextEvent sce) {
        Timer timer = new Timer();//执行我想要的任务,0秒延时,每10秒执行一次
        timer.schedule(new MyTask(list, lock), 0, 10 * 1000);
    }public void sessionCreated(HttpSessionEvent se) {//只要Session一创建了,就应该添加到容器中synchronized (lock) {
            list.add(se.getSession());
        }
        System.out.println("Session被创建啦");
    }public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session被销毁啦。");
    }public void contextDestroyed(ServletContextEvent sce) {
    }
}
  • 任务代码:

/*
* 在任务中应该扫描容器,容器在监听器上,只能传递进来了。
*
* 要想得到在监听器上的锁,也只能是传递进来
*
* */
class MyTask extends TimerTask {

    private List sessions;private Object lock;public MyTask(List sessions, Object lock) {this.sessions = sessions;this.lock = lock;
    }@Overridepublic void run() {synchronized (lock) {//遍历容器for (HttpSession session : sessions) {//只要15秒没人使用,我就移除它啦if (System.currentTimeMillis() - session.getLastAccessedTime() > (1000 * 15)) {
                    session.invalidate();
                    sessions.remove(session);
                }
            }
        }
    }
}
  • 测试:

15秒如果Session没有活跃,那么就被删除!

3d95b77b5cc4c7995f2f9b5cdd9ac4d5.gif

  • 使用集合来装载我们所有的Session

  • 使用定时器来扫描session的声明周期【由于定时器没有session,我们传进去就好了】

  • 关于并发访问的问题,我们在扫描和检测session添加的时候,同步起来就好了【当然,定时器的锁也是要外面传递进来的】


踢人小案列

列出所有的在线用户,后台管理者拥有踢人的权利,点击踢人的超链接,该用户就被注销了。

分析

首先,怎么能列出所有的在线用户呢??一般我们在线用户都是用Session来标记的,所有的在线用户就应该用一个容器来装载所有的Session。。

我们监听Session的是否有属性添加(监听Session的属性有添加、修改、删除三个方法。如果监听到Session添加了,那么这个肯定是个在线用户!)。

装载Session的容器应该是在Context里边的【属于全站点】,并且容器应该使用Map集合【待会还要通过用户的名字来把用户踢了】

思路:

  • 写监听器,监听是否有属性添加在Session里边了

  • 写简单的登陆页面。

  • 列出所有的在线用户

  • 实现踢人功能(也就是摧毁Session)

代码

  • 监听器

public class KickPerson implements HttpSessionAttributeListener {

    // Public constructor is required by servlet spec
    public KickPerson() {
    }

    public void attributeAdded(HttpSessionBindingEvent sbe) {

        //得到context对象,看看context对象是否有容器装载Session
        ServletContext context = sbe.getSession().getServletContext();

        //如果没有,就创建一个呗
        Map map = (Map) context.getAttribute("map");
        if (map == null) {
            map = new HashMap();
            context.setAttribute("map", map);
        }

        //---------------------------------------------------------------------------------------

        //得到Session属性的值
        Object o = sbe.getValue();

        //判断属性的内容是否是User对象
        if (o instanceof User) {
            User user = (User) o;
            map.put(user.getUsername(), sbe.getSession());
        }
    }

    public void attributeRemoved(HttpSessionBindingEvent sbe) {
      /* This method is called when an attribute
         is removed from a session.
      */
    }

    public void attributeReplaced(HttpSessionBindingEvent sbe) {
      /* This method is invoked when an attibute
         is replaced in a session.
      */
    }
}
  • 登陆页面

<form action="${pageContext.request.contextPath }/LoginServlet" method="post">
    用户名:<input type="text" name="username">
    <input type="submit" value="登陆">
form>
  • 处理登陆Servlet

//得到传递过来的数据
String username = request.getParameter("username");

User user = new User();
user.setUsername(username);

//标记该用户登陆了!
request.getSession().setAttribute("user", user);

//提供界面,告诉用户登陆是否成功
request.setAttribute("message", "恭喜你,登陆成功了!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
  • 列出在线用户

"${map}" var="me">
    ${me.key} "${pageContext.request.contextPath}/KickPersonServlet?username=${me.key}">踢了他吧
  • 处理踢人的Servlet

String username = request.getParameter("username");

//得到装载所有的Session的容器
Map map = (Map) this.getServletContext().getAttribute("map");

//通过名字得到Session
HttpSession httpSession = (HttpSession) map.get(username);
httpSession.invalidate();
map.remove(username);

//摧毁完Session后,返回列出在线用户页面
request.getRequestDispatcher("/listUser.jsp").forward(request, response);

测试

使用多个浏览器登陆来模拟在线用户(同一个浏览器使用的都是同一个Session)

8aab5fdbac1b7c2e2d93e15bd2118c6b.gif


监听Seesion的创建和监听Session属性的变化有啥区别???

  • Session的创建只代表着浏览器给服务器发送了请求。会话建立

  • Session属性的变化就不一样了,登记的是具体用户是否做了某事(登陆、购买了某商品)

最后

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

6d53848c9865586b5aa5d7ddb1a2cf5d.png

有帮助?好看!转发!f8c4a1b2a0be578284ee19eeb7ff78e0.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_725426.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在VS2010中将AspNet网站编译成一个DLL

在VS2010中创建一个网站&#xff0c;部署时网站的dll是动态生成的&#xff0c;每次编译产生的dll的名称都不一样&#xff0c;这样会导致在部署时必须将aspx页面和dll一起部署&#xff0c;尽管有时你可能只修改了后台代码。这样就变得很不方便&#xff0c;在VS2010中可以借助一个…

个人笔记、建站利器:PmWiki

什么是Wiki&#xff0c;能做什么 如果不知道什么是wiki&#xff0c;可以去百度百科查查&#xff0c;另外百度百科就是个wiki&#xff0c;:-D。wiki的优点在于任何有权限的人都可以编辑&#xff0c;在编辑过程中可以链接到别的wiki页面&#xff0c;如果目标wiki页不存在&#xf…

网站DDOS***防护实战老男孩经验心得分享

网站DDOS***防护实战老男孩经验心得分享 老男孩由于要培训学生、批改作业&#xff0c;因此最近比较忙&#xff0c;还要经常写书、录视频&#xff0c;搞的思路混乱&#xff0c;受朋友邀请参加某论坛活动&#xff0c;推迟不过&#xff0c;挤了一点时间&#xff0c;给大家简单分…

40 个新鲜的电商网站设计

为什么80%的码农都做不了架构师&#xff1f;>>> 1) Desina Desina 2) Mykea Mykea 3) IWC Schaffhausen IWC Schaffhausen 4) LRG LRG 5) Style And Conscience Style And Conscience 6) Crumpler Crumpler 7) Hungarian Wine Society Hungarian Wine Society 8 ) …

2011年国外最受欢迎的15个儿童网站

2019独角兽企业重金招聘Python工程师标准>>> 面向全球电子商务知识库网站eBizMBA公布了2011年国外最受欢迎的15个儿童网站&#xff1a; 1 Nick (http://www.nick.com) eBizMBA排名第932&#xff0c;估计每月访客4800000人&#xff0c;竞争力排名第159&#xff0c;Qu…

45个精品的网站图标集合推荐

精心设计和免费的图标在生活当中总是能派上用场&#xff0c;特别是在设计时&#xff0c;我们需要应用在最新的网站博客或应用程序当中使用它们。如果平时没有很好的积累这时候&#xff0c;通常会上网搜索&#xff0c;不仅费时间而且费时&#xff0c;在这篇文章中&#xff0c;我…

php小型购物网站,PHP实现一个多功能购物网站

本篇文章主要介绍如何用PHP实现一个多功能购物网站&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。一、需要实现的页面&#xff1a;Index.aspx&#xff1a;浏览商品页面&#xff0c;显示商品列表&#xff0c;用户可以点击“加入购物车“。ViewCart.aspx&#…

网站系统安全开发手册

为什么80%的码农都做不了架构师&#xff1f;>>> 网站系统安全开发手册 《网站系统安全开发手册》是国内首本在网站系统安全开发规范方面的应用手册&#xff0c;由动易软件精心编制而成...更多<< 转载于:https://my.oschina.net/u/856019/blog/111018

建站用什么cms_企业建站,云优CMS与易优CMS哪个好?

说到企业建站,云优CMS与易优CMS哪个好,我们从以下方面给出比较&#xff1a;一、建站系统授权费用从云优CMS与易优CMS二者官网&#xff0c;分别可以看出&#xff1a;云优CMS企业建站系统&#xff0c;有免费版、价格为198元的默认模板授权版以及398元起的商业模板授权版&#xff…

轻量级小型网站导航条

本博文&#xff0c;教大家做一个轻量级的小型网站的导航条。在网站的后台管理界面&#xff0c;就是可以管理这些导航内容。添加&#xff0c;删除&#xff0c;更新等&#xff0c;在后台能够预览到导航条效果。做到信息存储&#xff0c;需要在数据库创建相关的表。对表进行操作&a…

docker php 端口号,群晖使用Docker安装LNMP建站 无80端口 用443端口https访问

自己使用群晖搭建网站的过程&#xff0c;成功案例 &#x1f642; &#xff0c;不多描述其它系统有Docker的适用。见图开始之前有必要了解下LNMP&#xff0c;见&#xff1a;http://lnmp.org。这是一套非常优秀、便捷的一键脚本群晖安装Docker打开套件中心&#xff0c;左侧 全部 …

客户端 网站 服务器的关系,客户端与服务器关系

客户端与服务器关系 内容精选换一换Flink使用Windows环境进行开发&#xff0c;运行环境则建议部署在Linux环境下。您可以执行如下操作完成客户端的配置。确认服务端Flink组件已经安装。下载Flink客户端程序。登录MRS Manager。单击“服务管理 > Flink > 下载客户端”&…

手机版网站起码要实现一些基本的功能

2019独角兽企业重金招聘Python工程师标准>>> 手机版网站起码要实现一些基本的功能吧&#xff1a;1.页面的适用性问题。对于移动终端&#xff0c;有不一样的分辨率与屏幕尺寸&#xff0c;如果还像电脑端的设计还限制网页的宽度为1003px或其他像素值&#xff0c;字体大…

ajax异步刷新详细应用(网站响应速度优化)

2019独角兽企业重金招聘Python工程师标准>>> 尝试用jquery写的ajax异步刷新并且组织html文档 $("li.mod_cate").bind("mouseover",function(){//解决鼠标移动到子模块中还会触发ajax的问题var type $(this).attr("name");$.ajax(&qu…

php网站分工,[PHP]swoole_server几个过程的分工

$client new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);//设置事件回调函数$client->on("connect", function($cli) {$cli->send("hello world\n");});$client->on("receive", function($cli, $data){echo "Received: …

旅游网站的网页设计代码_网站设计和网页设计

网站设计和网页设计,牛推科技上海网络推广公司致力于企事业网络整合营销服务。提供全新的网络整合营销解决方案。根据企业行业特点和自身需求整合企业网络资源、提供长期的网络营销服务支持&#xff0c;帮助企业进行高起点的网络营销活动&#xff0c;让您和您的企业脱颖而出&am…

delphi edit里面的文字如何添加下划线_wordpress网站模板开发中,怎样给侧边栏,添加热门标签?...

使用过wordpress网站的朋友都知道&#xff0c;wordpress的tag标签是非常受欢迎的&#xff0c;尤其受到百度这样的搜索引擎的青睐。我就记得&#xff0c;我第一个wordpress网站&#xff0c;新发表的文章还没有被百度收录&#xff0c;而这篇文章的tag标签却被收录&#xff0c;而且…

flac转mp3_IOS/安卓ZAMZAR免费的“影片转音乐”网站,在线免安装!

ZAMZAR免费的影片转音乐网站&#xff0c;免安装软体、免注册&#xff0c;只要打开网页&#xff0c;就能线上将影片转成MP3&#xff0c;除了转成纯音乐的档案外&#xff0c;也包含多种格式的转换&#xff0c;3步骤轻松把MP4转GIF。 -无需下载软件。只需选择您的文件&#xff0c;…

网站建设技术方案_高端网站建设方案:如何进行网站建设策划

高端网站建设方案是高端网站建设的前期&#xff0c;网络公司一定要给到客户的信息。网站建设方案不仅是为了让客户能够深入了解互联网价值&#xff0c;同时也能够帮助企业了解网站带来的价值&#xff0c;并以各种表现形式和功能&#xff0c;将互联网的价值表达到位&#xff0c;…

SharePoint 开启网站匿名访问图文详解

SharePoint 开启网站匿名&#xff0c;需要先开启web application的匿名访问&#xff0c;然后开启site的匿名访问。特别的&#xff0c;site可以选择整个网站开启或者列表和库开启匿名&#xff0c;如果选择列表和库开启匿名&#xff0c;还需要对相应列表进行设置。 下面&#xff…