Java Web开发在线人数统计程序.docx
- 文档编号:6957168
- 上传时间:2023-01-13
- 格式:DOCX
- 页数:13
- 大小:45.83KB
Java Web开发在线人数统计程序.docx
《Java Web开发在线人数统计程序.docx》由会员分享,可在线阅读,更多相关《Java Web开发在线人数统计程序.docx(13页珍藏版)》请在冰豆网上搜索。
JavaWeb开发在线人数统计程序
JavaWeb开发——在线人数统计程序
作者:
孙鑫 来源:
程序员之家 发布者:
admin
时间:
2009-07-2410:
07:
00 点击:
3904
下面,我们利用HttpSessionBindingListener接口Java语言,编写一个在线人数统计的程序。
当一个用户登录后,显示欢迎信息,同时显示出当前在线的总人数和用户名单。
当一个用户退出登录或者Session超时值发生时,从在线用户名单中删除这个用户,同时将在线的总人数减1。
这个功能的完成,主要是利用一个实现了HttpSessionBindingListener接口的对象,当这个对象被绑定到Session中或者从Session中被删除时,更新当前在线的用户名单。
实例的开发主要有以下步骤。
Step1:
配置Web应用程序的运行目录
在%CATALINA_HOME%\conf\Catalina\localhost\目录下新建ch15.xml文件,输入如例15-4所示的内容。
例15-4ch15.xml
\JSPLesson\ch15"reloadable="true"/> Step2: 编写login.html 将编写好的login.html文件放到F: \JSPLesson\ch15\online目录下。 完整的代码如例15-5所示。 例15-5login.html
请输入用户名: | |
请输入密码: | |
Step3:
编写UserList.java,User.java,OnlineUserServlet.java和LogoutServlet.java
为了和本章其他例子中的类相区别,本例中的类定义在org.sunxin.ch15.online包中。
编写UserList.java,User.java,OnlineUserServlet.java和LogoutServlet.java源文件,将编写好的源文件放到F:
\JSPLesson\ch15\src\online目录下。
UserList.java的完整代码如例15-6所示。
例15-6UserList.java
1.packageorg.sunxin.ch15.online;
2.
3.importjava.util.Vector;
4.importjava.util.Enumeration;
5.
6.publicclassUserList
7.{
8.privatestaticfinalUserListuserList=newUserList();
9.privateVector
10.
11.privateUserList()
12.{
13.v=newVector
14.}
15.
16.publicstaticUserListgetInstance()
17.{
18.returnuserList;
19.}
20.
21.publicvoidaddUser(Stringname)
22.{
23.if(name!
=null)
24.v.addElement(name);
25.}
26.
27.publicvoidremoveUser(Stringname)
28.{
29.if(name!
=null)
30.v.remove(name);
31.}
32.
33.publicEnumeration
34.{
35.returnv.elements();
36.}
37.
38.publicintgetUserCount()
39.{
40.returnv.size();
41.}
42.}
在UserList这个类的设计上,我们应用了单例(Singleton)设计模式,关于设计模式的知识,读者可以参看相关的书籍。
UserList是一个单例类,所谓单例类,是指一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例类的一个最重要的特点是类的构造方法是私有的,从而避免了外部利用该类的构造方法直接创建多个实例。
在代码的第8行,定义一个静态的常量userList,它表示了UserList类的一个对象。
在UserList类加载的时候,这个对象就产生了。
第11~14行,声明UserList类的构造方法为private,这是为了避免在外部使用UserList类的构造方法创建其对象。
要注意的是,如果在类中不写构造方法,那么Java编译器就会为这个类提供一个默认的不带参数的公开的构造方法,这样,在外部就可以通过类的构造方法创建对象了,那么UserList也就不再是一个单例类了。
既然UserList类的构造方法是私有的,那么在外部就不能用new去构造对象,于是在代码的第16~19行,定义了一个静态的方法getInstance(),在这个方法中,返回在类加载时创建的UserList类的对象。
因为getInstance()方法本身是静态的,所以可以直接通过类名来调用。
那么为什么要将UserList设计成单例类呢?
这是因为UserList类的对象是用于存储和获取在线用户的列表,而这个用户列表对于所有的页面来说都应该是同一个,所以将UserList类设计成单例类,这样,所有的类访问的就是同一个UserList对象了。
代码的第9行,定义了一个私有的Vector类型的变量,在UserList类的构造方法中,对Vector类型的变量v进行了初始化,用于存放String类型的对象。
注意,在这个地方没有使用ArrayList,是考虑到UserList对象可能会被多个线程同时访问,因为ArrayList不是同步的,而Vector是同步的,所以采用Vector来保存用户列表。
User.java的完整代码如例15-7所示。
例15-7User.java
1.packageorg.sunxin.ch15.online;
2.
3.importjavax.servlet.http.HttpSessionBindingListener;
4.importjavax.servlet.http.HttpSessionBindingEvent;
5.
6.publicclassUserimplementsHttpSessionBindingListener
7.{
8.privateStringname;
9.privateUserListul=UserList.getInstance();
10.
11.publicUser()
12.{
13.}
14.publicUser(Stringname)
15.{
16.this.name=name;
17.}
18.publicvoidsetName(Stringname)
19.{
20.this.name=name;
21.}
22.publicStringgetName()
23.{
24.returnname;
25.}
26.publicvoidvalueBound(HttpSessionBindingEventevent)
27.{
28.ul.addUser(name);
29.}
30.publicvoidvalueUnbound(HttpSessionBindingEventevent)
31.{
32.ul.removeUser(name);
33.}
34.}
User类实现了HttpSessionBindingListener接口,表示登录的用户。
代码第9行,通过UserList类的静态方法getInstance()得到UserList类的对象,第26~29行,当User对象加入到Session中时,Servlet容器将调用valueBound()方法,我们将用户的名字保存到用户列表中。
第30~33行,当User对象从Session中被删除时,Servlet容器将调用valueUnbound()方法,我们从用户列表中删除该用户。
OnlineUserServlet.java的完整代码如例15-8所示。
例15-8OnlineUserServlet.java
1.packageorg.sunxin.ch15.online;
2.
3.importjavax.servlet.*;
4.importjava.io.*;
5.importjavax.servlet.http.*;
6.importjava.util.Enumeration;
7.
8.publicclassOnlineUserServletextendsHttpServlet
9.{
10.publicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)
11.throwsServletException,IOException
12.{
13.req.setCharacterEncoding("gb2312");
14.Stringname=req.getParameter("user");
15.Stringpwd=req.getParameter("password");
16.
17.if(null==name||null==pwd||name.equals("")||pwd.equals(""))
18.{
19.resp.sendRedirect("login.html");
20.}
21.else
22.{
23.HttpSessionsession=req.getSession();
24.Useruser=(User)session.getAttribute("user");
25.if(null==user||!
name.equals(user.getName()))
26.{
27.user=newUser(name);
28.session.setAttribute("user",user);
29.}
30.
31.resp.setContentType("text/html;charset=gb2312");
32.PrintWriterout=resp.getWriter();
33.
34.out.println("欢迎用户"+name+"登录");
35.UserListul=UserList.getInstance();
36.out.println("
当前在线的用户列表:
");
37.Enumeration
38.inti=0;
39.while(enums.hasMoreElements())
40.{
41.out.println(enums.nextElement());
42.out.println(" ");
43.if(++i==10)
44.{
45.out.println("
");
46.}
47.}
48.out.println("
当前在线的用户数:
"+i);
49.out.println("
50.out.close();
51.}
52.}
53.
54.publicvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)
55.throwsServletException,IOException
56.{
57.doGet(req,resp);
58.}
59.}
OnlineUser类用于向用户显示欢迎信息、当前在线用户列表和在线用户数。
代码的第24~29行,首先从Session中获取名为user的属性对象,通过判断它是否为空来判断在此次会话中用户是否已经登录。
如果user对象不为null,那么接着判断在同一个会话中,用户是否更换了一个用户名登录。
如果user对象为空或者当前登录的用户名和先前登录的用户名不同,则以用户的当前登录名创建一个User对象,将这个对象绑定到Session中,这个时候,Servlet容器就会调用User对象的valueBound()方法,将这个用户的名字保存在用户列表中。
第35行,得到UserList类的对象。
第37行,得到用户列表的枚举对象。
第39~47行,循环取出在线用户的名字并输出,一旦输出超过10个用户名,就输出一个换行(
)。
第48行,输出当前在线的用户数。
第49行,输出“退出登录”的链接。
LogoutServlet.java的完整代码如例15-9所示。
例15-9LogoutServlet.java
1.packageorg.sunxin.ch15.online;
2.
3.importjavax.servlet.*;
4.importjava.io.*;
5.importjavax.servlet.http.*;
6.
7.publicclassLogoutServletextendsHttpServlet
8.{
9.publicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)
10.throwsServletException,IOException
11.{
12.resp.setContentType("text/html;charset=gb2312");
13.
14.HttpSessionsession=req.getSession();
15.Useruser=(User)session.getAttribute("user");
16.session.invalidate();
17.
18.PrintWriterout=resp.getWriter();
19.out.println("
20.out.println(user.getName()+",你已退出登录
");
21.out.println("
22.out.println("");
23.out.close();
24.}
25.}
LogoutServlet类用于退出登录。
代码第16行,调用HttpSession对象的invalidate()方法,使Session失效,从而删除绑定到这个Session中的User对象,Servlet容器就会调用这个User对象的valueUnbound()方法,从用户列表中删除该用户。
Step4:
编译上述四个Java源文件
打开命令提示符,进入到源文件所在的目录F:
\JSPLesson\ch15\src\online下,然后执行
javac-d..\..WEB-INF\classes*.java
在WEB-INF\classes目录下生成4个源文件对应的包和类文件。
Step5:
部署Servlet
编辑WEB-INF目录下的web.xml文件,添加对本例中的Servlet的配置,内容如例15-10所示。
例15-10web.xml
…
org.sunxin.ch15.online.OnlineUserServlet
…
实现HttpSessionBindingListener接口的监听器类不需要在web.xml中进行配置。
Step6:
运行在线人数统计程序
启动Tomcat服务器,打开IE浏览器,首先在地址栏中输入
http:
//localhost:
8080/ch15/online/login.html
出现登录页面后,输入用户名和密码,将看到如图15-1所示的页面。
读者可以再打开一个浏览器,输入http:
//localhost:
8080/ch15/online/login.html,然后登录,将看到如图15-2所示的页面。
图15-1OnlineUserServlet显示一个用户在线图15-2OnlineUserServlet显示有两个用户在线
读者可以退出其中一个用户的登录,然后刷新另外一个窗口中的页面,可以看到显示的在线用户数为1。
读者可以多打开几个浏览器,进行测试。
在线人数统计程序存在的问题:
在第5.2.4节“Session和Cookie的深入研究”中介绍过,如果用户没有退出登录而直接关闭了浏览器,那么在服务器端的Session中,这个用户仍然是存在的,直到Session的超时值发生。
所以在线人数统计只能做到在一个时间段内统计出大致的在线人数,而不能统计出精确的人数。
为了提高统计的精确性,可以在客户端设置脚本,当浏览器关闭时,自动向服务器发送一个请求,服务器收到这个请求后,使Session失效。
不过,这也不能做到100%的精确,因为还存在着客户端的浏览器异常终止,或者客户机器崩溃的可能。
转载请注明出处:
程序员之家http:
//www.sunxin.org
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java Web开发在线人数统计程序 Web 开发 在线 人数 统计 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)