最近在学习Javaweb相关的内容(不黑不吹之前对web开发零基础),下面通过一个统计在线人数的小栗子讲讲Servlet监听器吧

开发环境 eclipse  tomcat 7

先说说这个小栗子的构思:

首先要考虑的就是通过什么方式能够统计在线人数?很容易想到可以通过session来统计在线人数为什么不是request呢?因为request在请求结束时即服务器返回资源时就被销毁了,也就是说request的作用域不足以用以统计在线人数。服务器在第一次接受一个用户请求时会给该用户分配一个sessionid在有效期结束后或是用户主动关闭浏览器一段时间后session会被销毁,所以用session来统计在线人数是合情合理的。

接下来问题来了,知道了统计在线人数和session相关那么应该如何操作呢?下面说说Servlet监听器。

Servlet监听器只要就是用来对Web应用进行监听和控制的,功能接近Java的GUI程序的监听器,可以监听由于Web应用程序状态改变而引起的Servlet容器产生的相应事件,然后作出处理。

Servlet监听器分为Servlet上下文监听器,Http会话监听器,Servlet请求监听器。

既然用到了Session那我们先来看看Session相关的监听器吧。查看Apache文档

HttpSessionListener接口有两个方法对应的是session被创建和被销毁时调用的。定义一个监听器类实现HttpSessionListener接口代码如下所示

 package com.xiaoysec;

 import java.util.ArrayList;

 import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; /**
* Application Lifecycle Listener implementation class MyHttpSessionListener
*
*/ public class MyHttpSessionListener implements HttpSessionListener {
private int numberCount = 0; /**
* Default constructor.
*/
public MyHttpSessionListener() {
// TODO Auto-generated constructor stub
} /**
* @see HttpSessionListener#sessionCreated(HttpSessionEvent)
*/
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
numberCount++;
arg0.getSession().getServletContext()
.setAttribute("numberCount", numberCount);
} /**
* @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
*/
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
numberCount--;
arg0.getSession().getServletContext()
.setAttribute("numberCount", numberCount);
ArrayList<Userinfo> userlist = (ArrayList<Userinfo>) arg0.getSession()
.getServletContext().getAttribute("userlist");
if (SessionUtil.getUsersessionid(userlist, arg0.getSession().getId()) != null) {
userlist.remove(SessionUtil.getUsersessionid(userlist, arg0
.getSession().getId()));
}
} }

在Session被创建时numberCount++,在被销毁时numberCount--。这样,一个简单的在线人数统计功能就实现了,接下来完善一下,如果想看到客户端的ip信息又该怎么办呢?首先还是思考如何获取用户信息,很容易想到可以通过request获取客户端的信息。

定义一个封装用户信息的Javabean,代码如下:

 package com.xiaoysec;

 public class Userinfo {
private String sessionid;
private String ip;
private String recenttime; public String getSessionid() {
return sessionid;
} public void setSessionid(String sessionid) {
this.sessionid = sessionid;
} public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} public String getRecenttime() {
return recenttime;
} public void setRecenttime(String recenttime) {
this.recenttime = recenttime;
} }

定义一个类MyServletRquestListener实现ServletRequestListener接口,在该接口中定义了一个requestInitialized方法,在服务器端接收到客户端的请求时被调用,

代码如下:

 package com.xiaoysec;

 import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest; public class MyServletRquestListener implements ServletRequestListener {
private ArrayList<Userinfo> userlist; // 在綫用戶的list @Override
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub } /**
* 在初始化request的初始化中判斷是否存在user的信息(sessionid)如果不存在的話就保存在userlist中
*/
@Override
public void requestInitialized(ServletRequestEvent arg0) {
userlist = (ArrayList<Userinfo>) arg0.getServletContext().getAttribute("userlist");
if(userlist==null)
userlist = new ArrayList<Userinfo>();
HttpServletRequest req = (HttpServletRequest) arg0.getServletRequest();
String sessionid = req.getSession().getId();
if (SessionUtil.getUsersessionid(userlist, sessionid) == null) {
Userinfo user = new Userinfo();
user.setIp(req.getRemoteAddr());
user.setSessionid(sessionid);
user.setRecenttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date()));
userlist.add(user);
}
arg0.getServletContext().setAttribute("userlist", userlist);
} }

接着写一个SessionUtil类实现了getUsersessionid方法,代码如下:

 package com.xiaoysec;

 import java.util.ArrayList;

 public class SessionUtil {
public static Object getUsersessionid(ArrayList<Userinfo> userlist,String sessionid) {
for(int i=0;i<userlist.size();i++){
Userinfo info = userlist.get(i);
if(userlist.get(i).getSessionid().equals(sessionid)) //表示当前的sessionid用户存在于用户list中不需要
return info;
}
return null;
} }

在getUsersessionid中参数为userlist和sessionid,通过一个循环判断sessionid所指的用户是否在userlist中如果在的话就返回用户信息info,如果不在的话就返回null并在MyServletRquestListener的31行处添加进userlist。

最后是界面jsp展示

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
当前用户在线人数<%= application.getAttribute("numberCount") %><br/>
<%
ArrayList<com.xiaoysec.Userinfo> userlist = (ArrayList<com.xiaoysec.Userinfo>)request
.getServletContext().getAttribute("userlist");
if(userlist!=null){
for (int i=0;i<userlist.size();i++) {
com.xiaoysec.Userinfo info = userlist.get(i);
%>
ip:<%=info.getIp()%><br />
recentTime:<%=info.getRecenttime()%><br/>
sessionid:<%=info.getSessionid()%><br/>
<%
}}
%>
</body>
</html>

总结:通过这个小栗子只是对Servlet监听器有一个小小的了解,还是需要多看源码,理解过程,多代码,多思考,多总结。

Javaweb统计在线人数的小栗子的更多相关文章

  1. asp.net MVC 统计在线人数功能实现

    今天开发一个设计一个统计在线人数的统计.实现方式是在MVC 中,用户次执行一个Action请求完成后,向数据表中插入一条用户心跳记录,统计在线人数则是根据该记录,30分钟内有记录的用户则为在线状态. ...

  2. 利用php比较精确的统计在线人数的办法

    利用php比较精确的统计在线人数的办法,注意这里所说的精确是指个数,如果需要精确在时间上,则需要根据实际情况调整代码中的有效时间.(自己没有写,从别人那拿过来的,先放着然后再研究)<?php// ...

  3. (实用篇)php精确的统计在线人数的方法

    这是一个非常精确的,通过php实现统计在线人数的方法,想知道怎么实现的请耐心阅读. <?php $filename='online.txt';//数据文件 $cookiename='VGOTCN ...

  4. Application 统计在线人数

    MVC 统计在线人数: protected void Application_Start() { Application[; AreaRegistration.RegisterAllAreas(); ...

  5. PHP实现统计在线人数功能示例

    本文实例讲述了PHP实现统计在线人数的方法.分享给大家供大家参考,具体如下: 我记得ASP里面统计在线人数用application 这个对象就可以了.PHP怎么设计? PHP对session对象的封装 ...

  6. cookie小栗子-实现简单的身份验证

    关于Cookie Cookie是一种能够让网站Web服务器把少量数据储存到客户端的硬盘或内存里,或是从客户端的硬盘里读取数据的一种技术. 用来保存客户浏览器请求服务器页面的请求信息,可以在HTTP返回 ...

  7. SpringBoot+Shiro+Redis共享Session入门小栗子

    在单机版的Springboot+Shiro的基础上,这次实现共享Session. 这里没有自己写RedisManager.SessionDAO.用的 crazycake 写的开源插件 pom.xml ...

  8. SpringBoot+Shiro入门小栗子

    写一个不花里胡哨的纯粹的Springboot+Shiro的入门小栗子 效果如图: 首页:有登录注册 先注册一个,然后登陆 登录,成功自动跳转到home页 home页:通过认证之后才可以进 代码部分: ...

  9. 一个小栗子聊聊JAVA泛型基础

    背景 周五本该是愉快的,可是今天花了一个早上查问题,为什么要花一个早上?我把原因总结为两点: 日志信息严重丢失,茫茫代码毫无头绪. 对泛型的认识不够,导致代码出现了BUG. 第一个原因可以通过以后编码 ...

随机推荐

  1. uber在限制新司机加入了,看看新政策把

    您可以点击“车主奖励分组查询”输入您在系统注册的手机号查询您所在奖励分组 5月25日-5月31日 奖励明细 1. 成都优步合作车主第一组 奖励政策: (账户激活时间在2015年5月29日之前) *以下 ...

  2. Android在应用中依据包名启动另外一个APP

    以下为TestIntentData工程 MainActivity如下: package cn.testintentdata; import java.util.List; import android ...

  3. 2014-11-21 DHTMLX是什么

    什么是dhtmlx? dhtmlx是一套网页开发 的函式库,他提供了树状元件.数据方格组件.工具列等组件供开发 人员使用. dhtmlx组件是一个JavaScript 库,提供了一套完整的Ajax驱动 ...

  4. Deep Learning(深度学习)学习笔记整理系列之(二)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  5. iOS 使用UILocalizedIndexedCollation实现区域索引标题(Section Indexed Title)即拼音排序

    UITableView在行数相当多的时候,给人的感觉是非常笨重的.通常为了方便用户使用,采用的方法有:搜索框.按层级展示.区域索引标题. 前两种就不用介绍了,此文就介绍区域索引标题的实现. 区域索引标 ...

  6. ASP.Net中使用Report Service

    昨天研究以下Report Service,发现SQL Service自带的报表服务器也非常强大, 一,报表在不同的应用中表现形式 参考:http://www.cnitblog.com/yide/arc ...

  7. apache hide index.php

    <Directory "D:/usr/local/www">    AllowOverride all    Options +FollowSymLinks +SymL ...

  8. Hadoop经典面试题(转)

    单项选择题 1. 下面哪个程序负责 HDFS 数据存储. a)NameNode b)Jobtracker c)Datanode d)secondaryNameNode e)tasktracker 2. ...

  9. Models——英语学习小技巧之四

    Models  are very important, here model means role model, is kind of like a hero. It's  someone that ...

  10. DX9三角形顶点绕序的判断

    今天亲自实践了下,终于搞清楚了. 多边形都有2个侧面,观察坐标系中正面朝向摄像机的为多边形为正面朝向多边形,正面偏离摄像机的为多边形为背面朝向多边形,d3d会把背面朝向多边形剔除,即背面消隐. 使用 ...