最近在学习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接口代码如下所示
1 packagecom.xiaoysec;2
3 importjava.util.ArrayList;4
5 importjavax.servlet.annotation.WebListener;6 importjavax.servlet.http.HttpSessionEvent;7 importjavax.servlet.http.HttpSessionListener;8
9 /**
10 * Application Lifecycle Listener implementation class MyHttpSessionListener11 *12 */
13
14 public class MyHttpSessionListener implementsHttpSessionListener {15 private int numberCount = 0;16
17 /**
18 * Default constructor.19 */
20 publicMyHttpSessionListener() {21 //TODO Auto-generated constructor stub
22 }23
24 /**
25 *@seeHttpSessionListener#sessionCreated(HttpSessionEvent)26 */
27 public voidsessionCreated(HttpSessionEvent arg0) {28 //TODO Auto-generated method stub
29 numberCount++;30 arg0.getSession().getServletContext()31 .setAttribute("numberCount", numberCount);32 }33
34 /**
35 *@seeHttpSessionListener#sessionDestroyed(HttpSessionEvent)36 */
37 public voidsessionDestroyed(HttpSessionEvent arg0) {38 //TODO Auto-generated method stub
39 numberCount--;40 arg0.getSession().getServletContext()41 .setAttribute("numberCount", numberCount);42 ArrayList userlist = (ArrayList) arg0.getSession()43 .getServletContext().getAttribute("userlist");44 if (SessionUtil.getUsersessionid(userlist, arg0.getSession().getId()) != null) {45 userlist.remove(SessionUtil.getUsersessionid(userlist, arg046 .getSession().getId()));47 }48 }49
50 }
在Session被创建时numberCount++,在被销毁时numberCount--。这样,一个简单的在线人数统计功能就实现了,接下来完善一下,如果想看到客户端的ip信息又该怎么办呢?首先还是思考如何获取用户信息,很容易想到可以通过request获取客户端的信息。
定义一个封装用户信息的Javabean,代码如下:
1 packagecom.xiaoysec;2
3 public classUserinfo {4 privateString sessionid;5 privateString ip;6 privateString recenttime;7
8 publicString getSessionid() {9 returnsessionid;10 }11
12 public voidsetSessionid(String sessionid) {13 this.sessionid =sessionid;14 }15
16 publicString getIp() {17 returnip;18 }19
20 public voidsetIp(String ip) {21 this.ip =ip;22 }23
24 publicString getRecenttime() {25 returnrecenttime;26 }27
28 public voidsetRecenttime(String recenttime) {29 this.recenttime =recenttime;30 }31
32 }
定义一个类MyServletRquestListener实现ServletRequestListener接口,在该接口中定义了一个requestInitialized方法,在服务器端接收到客户端的请求时被调用,
代码如下:
1 packagecom.xiaoysec;2
3 importjava.text.SimpleDateFormat;4 importjava.util.ArrayList;5 importjava.util.Date;6
7 importjavax.servlet.ServletRequestEvent;8 importjavax.servlet.ServletRequestListener;9 importjavax.servlet.annotation.WebListener;10 importjavax.servlet.http.HttpServletRequest;11
12 public class MyServletRquestListener implementsServletRequestListener {13 private ArrayList userlist; //在綫用戶的list
14
15 @Override16 public voidrequestDestroyed(ServletRequestEvent arg0) {17 //TODO Auto-generated method stub
18
19 }20
21 /**
22 * 在初始化request的初始化中判斷是否存在user的信息(sessionid)如果不存在的話就保存在userlist中23 */
24 @Override25 public voidrequestInitialized(ServletRequestEvent arg0) {26 userlist = (ArrayList) arg0.getServletContext().getAttribute("userlist");27 if(userlist==null)28 userlist = new ArrayList();29 HttpServletRequest req =(HttpServletRequest) arg0.getServletRequest();30 String sessionid =req.getSession().getId();31 if (SessionUtil.getUsersessionid(userlist, sessionid) == null) {32 Userinfo user = newUserinfo();33 user.setIp(req.getRemoteAddr());34 user.setSessionid(sessionid);35 user.setRecenttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")36 .format(newDate()));37 userlist.add(user);38 }39 arg0.getServletContext().setAttribute("userlist", userlist);40 }41
42 }
接着写一个SessionUtil类实现了getUsersessionid方法,代码如下:
1 packagecom.xiaoysec;2
3 importjava.util.ArrayList;4
5 public classSessionUtil {6 public static Object getUsersessionid(ArrayListuserlist,String sessionid) {7 for(int i=0;i
10 returninfo;11 }12 return null;13 }14
15 }
在getUsersessionid中参数为userlist和sessionid,通过一个循环判断sessionid所指的用户是否在userlist中如果在的话就返回用户信息info,如果不在的话就返回null并在MyServletRquestListener的31行处添加进userlist。
最后是界面jsp展示
1
2 pageEncoding="UTF-8"%>
3
4
5
6
7
8
Insert title here9
10
11 当前用户在线人数
12
13 ArrayList userlist = (ArrayList)request14 .getServletContext().getAttribute("userlist");15 if(userlist!=null){16 for (int i=0;i
19 ip:
20 recentTime:
21 sessionid:
22
23 }}24 %>
25
26
总结:通过这个小栗子只是对Servlet监听器有一个小小的了解,还是需要多看源码,理解过程,多代码,多思考,多总结。