Java Web开发——在线人数统计程序

Step1编写login.html

15-5  login.html

<html>

    <head>

        <title>登录页面</title>

    </head>

    <body>

        <form action="online" method="post">

            <table>

                <tr>

                    <td>请输入用户名:</td>

                    <td><input type="text" name="user"></td>

                </tr>

                <tr>

                    <td>请输入密码:</td>

                    <td><input type="password" name="password"></td>

                </tr>

                <tr>

                    <td><input type="reset" value="重填"></td>

                    <td><input type="submit" value="登录"></td>

                </tr>

            </table>

        </form>

    </body>

</html>

Step2

 

15-6  UserList.java

 

1package org.sunxin.ch15.online;

2

3import java.util.Vector;

4import java.util.Enumeration;

5

6public class UserList

7{

8    private static final UserList userList=new UserList();

9    private Vector<String> v;

10   

11   private UserList()

12   {

13        v=new Vector<String>();

14   }

15

16   public static UserList getInstance()

17   {

18        return userList;

19   }

20   

21   public void addUser(String name)

22   {

23        if(name!=null)

24            v.addElement(name);

25   }

26   

27   public void removeUser(String name)

28   {

29        if(name!=null)

30              v.remove(name);

31   }

32   

33   public Enumeration<String> getUserList()

34   {

35        return v.elements();

36   }

37   

38   public int getUserCount()

39   {

40        return v.size();

41   }

42}

在代码的第1619行,定义了一个静态的方法getInstance(),在这个方法中,返回在类加载时创建的UserList类的对象。因为getInstance()方法本身是静态的,所以可以直接通过类名来调用。

那么为什么要将UserList设计成单例类呢?这是因为UserList类的对象是用于存储和获取在线用户的列表,而这个用户列表对于所有的页面来说都应该是同一个,所以将UserList类设计成单例类,这样,所有的类访问的就是同一个UserList对象了。

注意,在这个地方没有使用ArrayList,是考虑到UserList对象可能会被多个线程同时访问,因为ArrayList不是同步的,而Vector是同步的,所以采用Vector来保存用户列表。

15-7  User.java

1 package org.sunxin.ch15.online;

2

3 import javax.servlet.http.HttpSessionBindingListener;

4 import javax.servlet.http.HttpSessionBindingEvent;

5

6 public class User implements HttpSessionBindingListener

7 {

8      private String name;

9      private UserList ul=UserList.getInstance();

10   

11     public User()

12     {

13     }

14     public User(String name)

15     {

16          this.name=name;

17     }

18     public void setName(String name)

19     {

20          this.name=name;

21     }

22     public String getName()

23     {

24          return name;

25     }

26     public void valueBound(HttpSessionBindingEvent event)

27     {

28          ul.addUser(name);

29     }

30     public void valueUnbound(HttpSessionBindingEvent event)

31     {

32          ul.removeUser(name);

33     }

34}

User类实现了HttpSessionBindingListener接口,表示登录的用户。代码第9通过UserList类的静态方法getInstance()得到UserList类的对象,第2629行,当User对象加入到Session中时,Servlet容器将调用valueBound()方法,我们将用户的名字保存到用户列表中。第3033行,当User对象从Session中被删除时,Servlet容器将调用valueUnbound()方法,我们从用户列表中删除该用户。

15-8  OnlineUserServlet.java

1package org.sunxin.ch15.online;

2

3import javax.servlet.*;

4import java.io.*;

5import javax.servlet.http.*;

6import java.util.Enumeration;

7

8public class OnlineUserServlet extends HttpServlet

9{

10    public void doGet(HttpServletRequest req, HttpServletResponse resp)

11                     throws ServletException,IOException

12    {

13        req.setCharacterEncoding("gb2312");

14        String name=req.getParameter("user");

15        String pwd=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              HttpSession session=req.getSession();

24              User user=(User)session.getAttribute("user");

25              if(null==user || !name.equals(user.getName()))

26              {

27                  user=new User(name);

28                  session.setAttribute("user",user);

29              }

30           

31              resp.setContentType("text/html;charset=gb2312");

32              PrintWriter out=resp.getWriter();

33           

34              out.println("欢迎用户<b>"+name+"</b>登录");

35              UserList ul=UserList.getInstance();

36              out.println("<br>当前在线的用户列表:<br>");

37              Enumeration<String> enums=ul.getUserList();

38              int i=0;

39              while(enums.hasMoreElements())

40              {

41                  out.println(enums.nextElement());

42                  out.println("&nbsp;&nbsp;&nbsp;&nbsp;");

43                  if(++i==10)

44                  {

45                       out.println("<br>");

46                  }

47              }

48              out.println("<br>当前在线的用户数:"+i);

49              out.println("<p><a href=logout>退出登录</a>");

50              out.close();

51        }

52    }

53   

54    public void doPost(HttpServletRequest req, HttpServletResponse resp)

55                    throws ServletException,IOException

56    {

57        doGet(req,resp);

58    }

59}

OnlineUser类用于向用户显示欢迎信息、当前在线用户列表和在线用户数。代码的第2429行,首先从Session中获取名为user的属性对象,通过判断它是否为空来判断在此次会话中用户是否已经登录。如果user对象不为null,那么接着判断在同一个会话中,用户是否更换了一个用户名登录。如果user对象为空或者当前登录的用户名和先前登录的用户名不同,则以用户的当前登录名创建一个User对象,将这个对象绑定到Session中,这个时候,Servlet容器就会调用User对象的valueBound()方法,将这个用户的名字保存在用户列表中。第35行,得到UserList类的对象。第37行,得到用户列表的枚举对象。第3947行,循环取出在线用户的名字并输出,一旦输出超过10个用户名,就输出一个换行(<br>)。第48行,输出当前在线的用户数。第49行,输出“退出登录”的链接。

15-9  LogoutServlet.java

1 package org.sunxin.ch15.online;

2

3 import javax.servlet.*;

4 import java.io.*;

5 import javax.servlet.http.*;

6

7 public class LogoutServlet extends HttpServlet

8 {

9     public void doGet(HttpServletRequest req, HttpServletResponse resp)

10               throws ServletException,IOException

11   {

12      resp.setContentType("text/html;charset=gb2312");

13       

14      HttpSession session=req.getSession();

15      User user=(User)session.getAttribute("user");

16      session.invalidate();

17       

18      PrintWriter out=resp.getWriter();

19      out.println("<html><head><title>退出登录</title></head><body>");

20      out.println(user.getName()+",你已退出登录<br>");

21      out.println("<a href=login.html>重新登录</a>");

22      out.println("</body></html>");

23      out.close();

24   }

25}

LogoutServlet类用于退出登录。代码第16行,调用HttpSession对象的invalidate()方法,使Session效,从而删除绑定到这个Session中的User对象,Servlet容器就会调用这个User对象的valueUnbound()方法,从用户列表中删除该用户。

Step3

15-10  web.xml

<servlet>

    <servlet-name>OnlineUserServlet</servlet-name>

    <servlet-class>

org.sunxin.ch15.online.OnlineUserServlet

</servlet-class>

</servlet>

 

<servlet-mapping>

    <servlet-name>OnlineUserServlet</servlet-name>

    <url-pattern>/online/online</url-pattern>

</servlet-mapping>

 

<servlet>

    <servlet-name>logout</servlet-name>

    <servlet-class>org.sunxin.ch15.online.LogoutServlet</servlet-class>

</servlet>

 

<servlet-mapping>

    <servlet-name>logout</servlet-name>

    <url-pattern>/online/logout</url-pattern>

</servlet-mapping>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值