Servlet用监听器统计在线用户显示

一.数据库的基本类
 

package com.hlx.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 操作基类
 * 
 * @author Administrator
 * 
 */
public class BaseDao {
	// 具体对象
	private Connection con;
	private PreparedStatement ps;
	// 参数
	private String driver = "com.mysql.jdbc.Driver";
	private String url = "jdbc:mysql://localhost:3306/food?useUnicode=true&characterEncoding=utf8&useOldAliasMetadataBehavior=true";
	private String username = "root";
	private String password = "xxxx";

	/**
	 * 1.连接数据库
	 * 
	 * @throws Exception
	 */
	public BaseDao() throws Exception {
		Class.forName(driver);
		this.con = DriverManager.getConnection(url, username, password);
	}

	/**
	 * 2.执行查询
	 * 
	 * @param sql
	 * @param args
	 * @return
	 * @throws Exception
	 */
	public ResultSet executeSelect(String sql, Object... args) throws Exception {
		ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		return ps.executeQuery();
	}

	/**
	 * 3.执行添加,删除,更新
	 * 
	 * @param sql
	 * @param args
	 * @return
	 * @throws Exception
	 */
	public boolean executeSQL(String sql, Object... args) throws Exception {
		ps = con.prepareStatement(sql);
		// 设置参数的值
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		// 执行判断
		if (ps.executeUpdate() != 1) {
			return false;
		}
		return true;
	}

	/**
	 *4. 关闭数据库的连接
	 * 
	 * @throws Exception
	 */
	public void closeAll() throws Exception {
		if (!con.isClosed() || con != null) {
			con.close();
		}
	}
}

 

二.监听器

 

import java.sql.ResultSet;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.hlx.util.BaseDao;

/**
 * ServletRequestListener表示用户访问任意个网址,每访问一个网页则监听/触发一次,实际上就是监听request对象;
 * ServletContextListener服务器的开始与结束监听触发一次
 * ,实际上就是监听Application对象,通过对Application对象的监听可以达到
 * 《【Servlet】利用load-on-startup创造一条随服务器共存亡的线程》
 * 
 * @author Administrator
 * 
 */
public class OnLineListener implements ServletContextListener,
		ServletRequestListener {

	/**
	 * application的开始相当于服务器的启动
	 */
	@Override
	public void contextInitialized(ServletContextEvent sce) {
 		 // 服务器一旦启动每5秒执行如下的任务  
		Timer timer =new Timer();
		timer.schedule(new Tasks(), 0, 5000);

	}

	/**
	 * 相当于服务器的停止,一切都消失了
	 */
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub

	}

	/**
	 * request对象的销毁没有用.
	 */
	@Override
	public void requestDestroyed(ServletRequestEvent sre) {
		// TODO Auto-generated method stub

	}

	/**
	 * request对象的创建相当于,用户访问任意个网页
	 */
	@Override
	public void requestInitialized(ServletRequestEvent sre) {
		// 有协议的请求对象
		HttpServletRequest request = (HttpServletRequest) sre
				.getServletRequest();

		// 获得会话对象
		HttpSession session = request.getSession();

		// 获得会话ID
		String id = session.getId();

		// 获得远程IP地址
		String ip = request.getRemoteAddr();

		// 结果集
		ResultSet rs = null;

		try {
			// 如果这个sessionID已经在在线用户列表里面的
		
			// 实例化对象
			BaseDao dao = new BaseDao();
			
			rs=dao.executeSelect("select * from online where sessionid=?", id);
			
			// 用户是在线的;那么更新其在线时间
			if(rs.next()){
		    	dao.executeSQL("update online set timeonline=? where sessionId=?", System.currentTimeMillis(),id);
			}else{
				 // 否则插入在线用户列表  
				dao.executeSQL("insert into online values(?,?,?)", id,ip,System.currentTimeMillis());
			}
			
			 // 把当前的在线用户列表放到application里面  
			rs = dao.executeSelect("select * from online");
			
			 // session.getServletContext()相当于application,用application存放在线用户列表  
			session.getServletContext().setAttribute("my", rs);

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

}

/**
 * TimerTask类是一个定时任务类,该类实现了Runnable接口,而且是一个抽象类
 * 
 * @author Administrator
 * 
 */
class Tasks extends TimerTask {

	@Override
	public void run() {
		// 对在线用户列表进行检查
		try {
			// 实例化对象
			BaseDao dao = new BaseDao();

			// 调用方法
			ResultSet rs = dao.executeSelect("select * from online");

			while (rs.next()) {
				// 如果当前时间距离用户上一次在线时间超过5分钟
				// 那么则从在线用户列表删除这个结果。
				if (System.currentTimeMillis() - rs.getLong("timeonline") > 5*60* 1000) {

					dao.executeSQL("delete from online where sessionid=?",
							rs.getString(1));
				}

			}

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

}

 

 

三.配置文件web.xml

 

 <listener>
   <listener-class>com.hlx.listen.OnLineListener</listener-class>
  </listener>

 

 

 

 

四.JSP页面

 

<table border="1" width="80%">
	<caption><h1>在线用户列表 </h1></caption>
		<tbody>
			<tr>
				<td>sessionId</td>
				<td>ip</td>
				<td>timeOnline</td>
			</tr>
			<%
			 ResultSet rs=(ResultSet)application.getAttribute("my");
			  while(rs.next()){
			 %>
			<tr>
				<td><%=rs.getString(1) %></td>
				<td><%=rs.getString(2) %></td>
				<td><%=rs.getLong(3) %></td>
			</tr>
			
			<%} %>
		</tbody>
	</table>

 

 

 

五.效果:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值