java session事件,Java开发网 - 再论Session事件的捕获
最近又有網(wǎng)友問到,如何用Session實(shí)現(xiàn)在線統(tǒng)計(jì)的功能,其實(shí)只要對(duì)Servlet規(guī)范詳細(xì)了解一下,明白其基本原理,編寫一個(gè)類似的功能并不是一件很復(fù)雜的事情。我以前的一篇文章,最初也是發(fā)表在JavaResearch上的(http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=2164),不過可能源碼沒有全部給出,只給出了最重點(diǎn)的源碼,所以還是有很多網(wǎng)友給我發(fā)信索取全部源碼。因?yàn)槟莻€(gè)項(xiàng)目是以前做的,所以我手頭上也沒有原來的代碼了,所以可能有的網(wǎng)友的要求就滿足不了了,在這里一并致歉。
第一篇文章是基于Servlet2.2規(guī)范編寫的,那時(shí)候沒有HttpSessionListener,鑒于目前絕大多數(shù)的應(yīng)用服務(wù)器都支持2.3的規(guī)范,所以為了回應(yīng)網(wǎng)友的提問,特地又基于2.3以上的規(guī)范編寫了一個(gè)簡(jiǎn)單的測(cè)試?yán)印?/p>
這個(gè)例子的最主要功能就是提供在線用戶列表顯示(既然用戶列表都可以顯示了,那人數(shù)統(tǒng)計(jì)自然也不在話下了)。
在給出代碼之前,先簡(jiǎn)單說一下監(jiān)聽器的常識(shí)。
HttpSessionListener:網(wǎng)友rdfei 在他的文章(http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=18541)中也已經(jīng)進(jìn)行了比較詳細(xì)的描述,這是2.3以上規(guī)范所提供的一個(gè)新功能,也就是可以定義監(jiān)聽器監(jiān)聽HttpSession對(duì)象的創(chuàng)建和銷毀。每當(dāng)有新的用戶訪問網(wǎng)站,應(yīng)用服務(wù)器會(huì)創(chuàng)建一個(gè)HttpSession對(duì)象,每當(dāng)Session超時(shí),應(yīng)用服務(wù)器則會(huì)銷毀這個(gè)對(duì)象。
HttpSessionBindingListener:每當(dāng)往Session中存入一個(gè)對(duì)象(setAttribute)或從Session中刪除一個(gè)對(duì)象的時(shí)候,如果這個(gè)對(duì)象實(shí)現(xiàn)了此監(jiān)聽器接口,應(yīng)用服務(wù)器將會(huì)自動(dòng)調(diào)用接口相應(yīng)的方法。
需要注意的一點(diǎn)就是,在sessionDestroyed方法和valueUnbound方法中,你可以得到HttpSession對(duì)象的實(shí)例,但是其getAttribute方法不再可用,也就是在這兩個(gè)方法中,你不能再次得到存入session中的對(duì)象。
基于以上這些粗淺的認(rèn)識(shí),再簡(jiǎn)單介紹一下我提供的測(cè)試?yán)拥那闆r:
測(cè)試?yán)涌偣舶缦挛募?#xff1a;
OnlineUserListener.java:它實(shí)現(xiàn)了HttpSessionListener接口
OnlineUsers.java:它包含了所有正在訪問網(wǎng)站的用戶信息,為了方便起見,它也實(shí)現(xiàn)了HttpSessionBindingListener接口(實(shí)際中你最好把他們分開吧)
User.java:這是用戶的信息
test.jsp:為了方便,我把登錄,退出,顯示在線用戶列表等功能都做在同一個(gè)jsp文件里了。
下面是具體的代碼:
/**
* OnlineUserListener.java
* Created on 2004-11-19
*/
package com.ccctc.view.web;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @author litf
*
*/
public class OnlineUserListener
implements HttpSessionListener {
/**
* 瀏覽器第一次訪問的時(shí)候,調(diào)用本方法
* @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
*/
public void sessionCreated(HttpSessionEvent event) {
User u = new User();
u.setName("guest");
u.setId(event.getSession().getId());
event.getSession().setAttribute("currentUser",u);
OnlineUsers.getInstance().addUser
;
}
/**
* Session超時(shí)的時(shí)候,調(diào)用本方法
* @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
*/
public void sessionDestroyed(HttpSessionEvent event) {
OnlineUsers.getInstance().removeUser(event.getSession().getId());
}
}
/**
* OnlineUsers.java
* Created on 2004-11-19
*/
package com.ccctc.view.web;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
/**
* @author litf
* 在線用戶統(tǒng)計(jì)
*/
public class OnlineUsers implements HttpSessionBindingListener{
private Map users = new HashMap();
private static OnlineUsers onlineUsers = new OnlineUsers();
public static OnlineUsers getInstance(){
return onlineUsers;
}
/**
* @return
*/
public Collection getUsers() {
return users.values();
}
public void addUser(User user) {
users.put(user.getId(),user);
}
public void removeUser(String userId){
users.remove(userId);
}
/**
* 對(duì)象實(shí)例(即OnlineUserListener的實(shí)例)作為一個(gè)屬性被設(shè)置到session的
* 時(shí)候,會(huì)調(diào)用本方法,這種情況一般發(fā)生在點(diǎn)擊登錄按鈕以后的處理過程中
* 設(shè)置
* @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
*/
public void valueBound(HttpSessionBindingEvent event) {
//現(xiàn)在暫時(shí)不需要額外處理,你可以在這里記錄日志等
}
/**
* 當(dāng)Session超時(shí),或本實(shí)例被從session中移除的時(shí)候被調(diào)用,這種情況一般
* 發(fā)生在注銷方法的處理過程中
* @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
*/
public void valueUnbound(HttpSessionBindingEvent event) {
try {
HttpSession session = event.getSession();
User u = (User)session.getAttribute("currentUser");
u.setName("guest");
} catch (RuntimeException e) {
//e.printStackTrace();
}
}
}
/**
* User.java
* Created on 2004-11-19
*/
package com.ccctc.view.web;
/**
* @author litf
*
*/
public class User{
private String address;
private String id;
private String name;
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof User)) {
return false;
}
if(this.id !=null && this.id.equals(((User)obj).getId())){
return true;
}
return false;
}
/**
* @return
*/
public String getAddress() {
return address;
}
/**
* @return
*/
public String getId() {
return id;
}
/**
* @return
*/
public String getName() {
return name;
}
/**
* @param string
*/
public void setAddress(String string) {
address = string;
}
/**
* @param string
*/
public void setId(String string) {
id = string;
}
/**
* @param string
*/
public void setName(String string) {
name = string;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "name:"+name + ",id:" + id + ",address:"+address;
}
}
test.jsp
User u = (User)session.getAttribute("currentUser");
String name = request.getParameter("user");
if(u != null){
String remote = request.getRemoteAddr();
u.setAddress(remote);
}
//User Login
if(name != null){
if(u != null){
session.setAttribute("_listener",OnlineUsers.getInstance());
u.setName(name);
}
}
//User Logout
String logout = request.getParameter("logout");
if(logout != null){
session.removeAttribute("_listener");
}
%>
current users:
java.util.Collection l = OnlineUsers.getInstance().getUsers();
for(java.util.Iterator it = l.iterator(); it.hasNext()
{
User tu = (User)it.next();
if(u.equals(tu))
{
%>
:
}else{
%>
:
}
}
%>
User :
Logout
refresh
web.xml文件中增加:
com.ccctc.view.web.OnlineUserListener
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的java session事件,Java开发网 - 再论Session事件的捕获的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab 维纳滤波恢复运动模糊,运动
- 下一篇: Java中值传递和引用传递原理以及区别