Java_JSP2_监听在线用户信息;

1、实现思路:通过检查HttpServletRequest监控在线用户的状况;

  a、采用ServletRequestListener监听器负责监听每次用户请求:当用户请求到达时,系统将用户请求的sessionID、用户名、用户IP、正在访问的资源、访问时间记录下来(新请求增加,旧请求更新记录;通过会话ID查询数据表是否存在来判断);

  b、启动后台线程,她每隔一段时间检查上面的每条在线记录,如果某条在线记录的访问时间与当前时间相差超过指定值,将这条在线记录删除;这线程应该随着应用的启动而启动,可考虑ServletContextListener来启动、销毁;

2、实现

=>RequestListener.java

<span style="font-size:18px;">	package lee;
	
	import javax.servlet.*;
	import javax.servlet.http.*;
	import javax.servlet.annotation.*;
	import java.sql.*;
	
	/**
	 * RequestListener_class
	 * description:在线用户_记录用户信息(每次用户请求到达时,如果是新的用户会话,将相关信息插入数据表;如果是老的用户会话,则更新数据表中已有的在线记录);
	 * date:17:02 2014-10-30;
	 * @author cyb_23
	 * @version  1.0
	 */
	@WebListener
	public class RequestListener implements ServletRequestListener
	{
		//当用户请求到达、被初始化时触发该方法
		public void requestInitialized(ServletRequestEvent sre)  
		{
			HttpServletRequest request = (HttpServletRequest)
				sre.getServletRequest();
			HttpSession session = request.getSession();
			
			//------记录信息------
			String sessionId = session.getId();	// 获取session ID;
			String ip = request.getRemoteAddr(); 	// 获取访问的IP;
			String page = request.getRequestURI();	// 访问的页面;
			String user = (String)session.getAttribute("user");
			user = (user == null) ? "游客" : user;	// 未登录用户当游客处理;

			try
			{
				DbDao dd = new DbDao("com.mysql.jdbc.Driver"
					, "jdbc:mysql://localhost:3306/online_inf"
					, "root"
					, "32147");
				ResultSet rs = dd.query("select * from online_inf where session_id=?"
					, true , sessionId);
				//如果该用户对应的session ID存在,表明是旧的会话
				if (rs.next())
				{
					//更新记录
					rs.updateString(4, page);
					rs.updateLong(5, System.currentTimeMillis());
					rs.updateRow();
					rs.close();
				}
				else
				{
					//插入该用户的在线信息
					dd.insert("insert into online_inf values(? , ? , ? , ? , ?)",
						sessionId , user , ip , page , System.currentTimeMillis());
				}
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
			}
		}
		//当用户请求结束、被销毁时触发该方法
		public void requestDestroyed(ServletRequestEvent sre) 
		{
		}
	}
</span>

=>OnlineListener.java

<span style="font-size:18px;">	package lee;
	
	import javax.servlet.*;
	import javax.servlet.annotation.*;
	import javax.servlet.http.*;
	
	import java.sql.*;
	import java.awt.event.*;
	
	/**
	 * OnlineListener_class
	 * description:ServletContextListener实例,负责启动后台线程,这线程将会定期检查在线记录,删除那些长时间没有重新请求过的记录;
	 * date:17:10 2014-10-30;
	 * @author cyb_23
	 * @version  1.0
	 */
	@WebListener
	public class OnlineListener 
		implements ServletContextListener
	{
		//超过该时间(10分钟)没有访问本站即认为用户已经离线
		public final int MAX_MILLIS = 10 * 60 * 1000;
	
		//应用启动时触发该方法
		public void contextInitialized(ServletContextEvent sce) 
		{
			//每5秒检查一次(使用计算器Timer)
			new javax.swing.Timer(1000 * 5 , new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					try
					{
						DbDao dd = new DbDao("com.mysql.jdbc.Driver"
							, "jdbc:mysql://localhost:3306/online_inf"
							, "root"
							, "32147");
						ResultSet rs = dd.query("select * from online_inf" , false);

						StringBuffer beRemove = new StringBuffer("(");
						while(rs.next())
						{
							//如果距离上次访问时间超过指定时间
							if ((System.currentTimeMillis() - rs.getLong(5))
								> MAX_MILLIS)
							{
								//将需要被删除的session ID添加进来
								beRemove.append("'");
								beRemove.append(rs.getString(1));
								beRemove.append("' , ");
							}
						}
						//有需要删除的记录
						if (beRemove.length() > 3)
						{
							beRemove.setLength(beRemove.length() - 3);
							beRemove.append(")");
							//删除所有“超过指定时间未重新请求的记录”
							dd.modify("delete from online_inf where session_id in "
								+ beRemove.toString());
						}
						dd.closeConn();
					}
					catch (Exception ex)
					{
						ex.printStackTrace();
					}
				}
			}).start();
		}
		public void contextDestroyed(ServletContextEvent sce) 
		{
		}
	}</span>

 =>DbDao.java

<span style="font-size:18px;"> 	package lee;

	import java.sql.*;
	
	/**
	 * DbDao_class
	 * description:数据库操作类;
	 * date:17:21 2014-10-30;
	 * @author cyb_23
	 * @version  1.0
	 */
	public class DbDao 
	{
		private Connection conn;
		private String driver;
		private String url;
		private String username;
		private String pass;
	
		public DbDao()
		{
		}
	
		public DbDao(String driver , String url 
			, String username , String pass)
		{
			this.driver = driver;
			this.url = url;
			this.username = username;
			this.pass = pass; 
		}
		//下面是各个成员属性的setter和getter方法
		public void setDriver(String driver) {
			this.driver = driver; 
		}
		public void setUrl(String url) {
			this.url = url; 
		}
		public void setUsername(String username) {
			this.username = username; 
		}
		public void setPass(String pass) {
			this.pass = pass; 
		}
		public String getDriver() {
			return (this.driver); 
		}
		public String getUrl() {
			return (this.url); 
		}
		public String getUsername() {
			return (this.username); 
		}
		public String getPass() {
			return (this.pass); 
		}
	
		//获取数据库连接
		public Connection getConnection() throws Exception
		{
			if (conn == null)
			{
				Class.forName(this.driver);
				conn = DriverManager.getConnection(url,username,pass);
			}
			return conn;
		}
	
		//插入记录
		public boolean insert(String sql , Object... args)
			throws Exception
		{
			PreparedStatement pstmt = getConnection().prepareStatement(sql);
			for (int i = 0; i < args.length ; i++ )
			{
				pstmt.setObject( i + 1 , args[i]);
			}
			if (pstmt.executeUpdate() != 1)
			{
				return false;
			}
			pstmt.close();
			return true;
		}
	
		//执行查询
		public ResultSet query(String sql , boolean updatable , Object... args )
			throws Exception
		{
			PreparedStatement pstmt = null;
			if (updatable)
			{
				//创建可更新的PreparedStatement
				pstmt = getConnection().prepareStatement(sql
					, ResultSet.TYPE_SCROLL_INSENSITIVE
					, ResultSet.CONCUR_UPDATABLE);
			}
			else
			{
				pstmt = getConnection().prepareStatement(sql);
			}

			for (int i = 0; i < args.length ; i++ )
			{
				pstmt.setObject( i + 1 , args[i]);
			}
			return pstmt.executeQuery();
		}
	
		//执行修改
		public void modify(String sql , Object... args)
			throws Exception
		{
			PreparedStatement pstmt = getConnection().prepareStatement(sql);
			for (int i = 0; i < args.length ; i++ )
			{
				pstmt.setObject(i + 1 , args[i]);
			}
			pstmt.executeUpdate();
			pstmt.close();
		}
	
		//关闭数据库连接的方法
		public void closeConn()
			throws Exception
		{
			if (conn != null && !conn.isClosed())
			{
				conn.close();
			}
		}
	}</span>




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值