监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。 分类:
按监听的对象划分,可以分为
ServletContext对象监听器 HttpSession对象监听器 ServletRequest对象监听器
按监听的事件划分
对象自身的创建和销毁的监听器 对象中属性的创建和消除的监听器 session中的某个对象的状态变化的监听器
示例:用监听器统计网站在线人数
原理:每当有一个访问连接到服务器时,服务器就会创建一个session来管理会话。那么我们就可以通过统计session的数量来获得当前在线人数。
监听器应用一般统计在线人数,闲着没事,写个笔记,我们项目中是这样做的
首先定义一个servlet 这个servelt 在服务器启动时,就会调用,初始化:
实现累计访问量的一个方法 1.web.xml的配置 <servlet > <servlet-name > VisitCounts</servlet-name > <servlet-class > com.sysware.framework.login.VisitCounts</servlet-class > <load-on-startup > 0</load-on-startup > </servlet >
2.项目登录页面可以获取访问本项目的总人数(init方法) package com.sysware.framework.login; import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException; import javax.servlet.http.HttpServlet; public class VisitCounts extends HttpServlet { private static final long serialVersionUID = -6737156348721467846L ; public static int counts = 0 ; public static void setCounts (int counts) { VisitCounts.counts = counts; } public int getCounts () { return counts; } public void init () { String p = this .getClass().getClassLoader().getResource("" ).getPath(); File file = new File (p+File.separator +"visitCount.txt" ); if (file.exists()) { readFile(file); } else { try { file.createNewFile(); readFile(file); } catch (IOException e) { e.printStackTrace(); } } } @SuppressWarnings("static-access") public void readFile (File file) { BufferedReader reader = null ; String tempString = null ; try { reader = new BufferedReader (new FileReader (file)); while ((tempString = reader.readLine()) != null ) { VisitCounts.counts = Integer.parseInt(tempString); System.out.println(); this .setCounts(counts); } } catch (Exception e) { e.printStackTrace(); } } }
3.在用户登录时,数量加1并用流写到文件里面(doLogin方法里面处理) if (loginInfo.isSuccess()) { VisitCounts.setCounts(VisitCounts.counts + 1 ); writeFile(); }<br><br> public void writeFile () {<br> <br> FileWriter filewrite = null ;<br> try {<br> <br>
以上,是实现累计访问量的一个方法;
下面说说实现在线人数,这个就要用到监听器的方式
实现在线人数 首先还是在 web.xml中配置你所写的监听器 <listener > <listener-class > com.sysware.framework.login.OnlineSessionListener</listener-class > </listener >
2.监听器类 package com.sysware.framework.login; import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent; import com.sysware.framework.commons.SystemConstants; public class OnlineSessionListener implements HttpSessionAttributeListener { @Override public void attributeAdded (HttpSessionBindingEvent event) { if (SystemConstants.SESSION_KEY.equals(event.getName())) { OnlineUserContext.getInstance().addSession(event.getSession()); } } @Override public void attributeRemoved (HttpSessionBindingEvent event) { if (SystemConstants.SESSION_KEY.equals(event.getName())) { OnlineUserContext.getInstance().removeSession(event.getSession()); } } @Override public void attributeReplaced (HttpSessionBindingEvent event) { if (SystemConstants.SESSION_KEY.equals(event.getName())) { OnlineUserContext.getInstance().replaceSession(event.getSession()); } } }
package com.sysware.framework.login;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.servlet.http.HttpSession;import com.sysware.framework.commons.SystemConstants;import com.sysware.framework.eobs.commons.ObjectCloneUtils;import com.sysware.utils.SyswareUtil;public class OnlineUserContext { private static OnlineUserContext onlineUserContext; private Map<String, HttpSession> onlineUserMap; private OnlineUserContext () { onlineUserMap = new HashMap <String, HttpSession>(); } public static OnlineUserContext getInstance () { return onlineUserContext == null ? onlineUserContext = new OnlineUserContext () : onlineUserContext; } synchronized void addSession (HttpSession session) { onlineUserMap.put(session.getId(), session); } synchronized void removeSession (HttpSession session) { if (onlineUserMap.containsKey(session.getId())) { onlineUserMap.remove(session.getId()); } } synchronized void replaceSession (HttpSession session) { addSession(session); } public boolean isLogged (String userId) { List<OnlineUserInfo> list = getOnlineUserInfoList(); for (OnlineUserInfo info : list) { if (info.isLogged() && info.getUserId().equals(userId)) { return true ; } } return false ; } public HttpSession getSession (String sessionId) { return onlineUserMap.containsKey(sessionId) ? onlineUserMap.get(sessionId) : null ; } public void removeSession (String sessionId) { HttpSession session = getSession(sessionId); if (!SyswareUtil.isEmpty(session)) { session.invalidate(); session = null ; } } public int getLoginUserCount () { int num = 0 ; List<OnlineUserInfo> list = getOnlineUserInfoList(); for (OnlineUserInfo info : list) { if (info.isLogged()) { num ++; } } return num; } public int getNoLoginUserCount () { int num = 0 ; List<OnlineUserInfo> list = getOnlineUserInfoList(); for (OnlineUserInfo info : list) { if (!info.isLogged()) { num ++; } } return num; } public int getOperatorCount () { return getOnlineUserInfoList().size(); } public synchronized List<OnlineUserInfo> getOnlineUserInfoList () { List<OnlineUserInfo> list = new ArrayList <OnlineUserInfo>(); Iterator<Entry<String, HttpSession>> iterator = onlineUserMap .entrySet().iterator(); while (iterator.hasNext()) { Entry<String, HttpSession> entry = iterator.next(); OnlineUserInfo info = ObjectCloneUtils.clone(getOnlineUserInfo(entry.getKey())); info.setSessionId(entry.getKey()); list.add(info); } return list; } private OnlineUserInfo getOnlineUserInfo (String sessionId) { HttpSession session = getSession(sessionId); return SyswareUtil.isEmpty(session) ? null : (Operator) session.getAttribute(SystemConstants.SESSION_KEY); } }
上面的方法,一个是在线统计人数,一个是实现总访问量,自己项目中运用的,做个笔记。
页面 <div class ="visit" > 当前访问数:<span id ="nowVisitCount" style ="color:#5374B1;" > <%=OnlineUserContext.getInstance().getLoginUserCount() %></span > </div > <div class ="count" > 累计访问数:<span id ="historyVisitCount" style ="color:#5374B1;" > <%=new LoginServiceImpl().getCounts()%></span > </div >