高效管理DWR中的ScriptSession,ScriptSessionLintener



高效管理DWR中的ScriptSession,ScriptSessionLintener

当我们在使用DWR的反向AJax是,每次页面的刷新都会产生一个ScriptSession(SS),但是我们确无从对过期的SS进行即使的销毁,虽然可以通过在每个页面访问时,自动执行某个方法,来销毁那些当前用户的非有效SS,但是这样也使得我们在代码管理上带来非常麻烦的问题.

DWR3的诞生终于给我们提供了ScritpSessionLintener(SSL)接口

本文,主要讲解如何使用ScriptSession接口.

 

DWR支持在Web.XML当中,配置扩展.

Xml代码 复制代码
<init-param>
<param-name>*</param-name>
<param-value>*</param-value>
</init-param>
[xml] view plaincopy
<init-param>
<param-name>*</param-name>
<param-value>*</param-value>
</init-param>

但是,经过几次的实验和摸索,SSL在当中配置后,管理器会进行有效构造,但是SS在创建和销毁时,并不会执行继承了ScriptSessionListner类的相关方法.(或许是我自己项目的问题.)

 

经过自己的研究发现,在ScriptSessionManager类中,包含了AddScriptSessionListener方()法.这样给使用SSL带来了方便

 

我们只需要在Web.XML文件中配置一个自定义的ScrptSessionManager

 

Java代码 复制代码
public class CustomScriptSessionManager extends org.directwebremoting.impl.DefaultScriptSessionManager {

public CustomScriptSessionManager(){
try {
this.addScriptSessionListener(new CustomScriptSessionListener());
} catch (Exception e) {
e.printStackTrace();
}
}
}
[java] view plaincopy
public class CustomScriptSessionManager extends org.directwebremoting.impl.DefaultScriptSessionManager {

public CustomScriptSessionManager(){
try {
this.addScriptSessionListener(new CustomScriptSessionListener());
} catch (Exception e) {
e.printStackTrace();
}
}
}

 

*CustomScriptSessionListener 为一个实现了ScriptSessionListener接口的实体类.

通过这种方式,将SS管理程序注射近SSM内,让管理器在SS状态发生变化时,即使通过SSL进行处理

 

如何使得每个用户的SS都是新鲜的,每个人都有自己的方法,我在自己的管理程序内使用一个

将每个用户的Session内存放当前ScriptSession进行绑定,当用户生成一个新的ScriptSession时,根据用户的Session,并且将旧的ScriptSession进行主动销毁,并更新Session.

 

这样,我们随着高效的保证每个用户只有一个ScriptSession存在于内存当中,使得我们的程序更加高效.

 

Java代码 复制代码
package com.dwr;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* 在线ScriptSession(SSL)监听管理器.
* 在SSL中,每当DWR工厂在生成一个新的ScriptSession(SS)时,将被SSL捕获
* SSL对捕获的SS进行初始化赋值
* 其中在SS属性中的SessionLabel.CurrentSesionID赋予当前用户的SessinID
* 并在改用户的Session属性中的SessionLabel.CurrentScriptSessionID赋予当前的SSL
* 然后在SessionLabel.CurrentPage中赋予当前SS的操作界面地址
*
* 并且开始激活SSL插件中的sessionCreated方法
*
* 当
* @author 熊浩华 – ibmsz
*
* 2009-8-18:下午03:11:55-
*/
public class CustomScriptSessionListener implements ScriptSessionListener {

public static final HttpSessionLabel SessionLabel = new HttpSessionLabel();

private Collection<IListenerMessage> collection = null;

public CustomScriptSessionListener() throws Exception{
System.out.println(“开始构造SSL”);
collection = new Vector<IListenerMessage>();
SAXReader reader = new SAXReader();
Document document = reader.read(this.getClass().getResource(“ScriptSessionListener.xml”));
Element rootElement = document.getRootElement();
Iterator it = rootElement.elementIterator(“listener”);
while(it.hasNext() && it != null){
Element element = (Element)it.next();
String classPath = element.getTextTrim();
if(classPath == null || classPath.trim().equals(“”)){
continue;
}
Class cls = Class.forName(classPath);
Object object = cls.newInstance();
if(object instanceof IListenerMessage){
this.collection.add((IListenerMessage)object);
}
}
}


@SuppressWarnings(“deprecation”)
public final void sessionCreated(ScriptSessionEvent sSessionEvent) {
// System.out.println(“创建新的ScriptSession时执行”);
ScriptSession scriptSession = sSessionEvent.getSession(); //获取新创建的SS
WebContext webContext = WebContextFactory.get();
HttpServletRequest httpServletRequest = webContext.getHttpServletRequest();
HttpSession httpSession = httpServletRequest.getSession(); //获取构造SS的用户的HttpSession
ScriptSession currSession = (ScriptSession)httpSession.getAttribute(SessionLabel.getCurrentScriptSessionID());
if(currSession != null){
currSession.invalidate();
}
for(IListenerMessage message : this.collection){
message.sessionCreated(sSessionEvent);
}
httpSession.setAttribute(“DWR3.CurrPath”, scriptSession.getPage());
httpSession.setAttribute(“DWR3.CurrScriptSession”, scriptSession);
Collection<ScriptSession> sSCollection = webContext.getScriptSessionsByPage(scriptSession.getPage());
for(ScriptSession session : sSCollection){
if(session.getAttribute(SessionLabel.getCurrentSesionID()) == null){
continue;
}
for(IListenerMessage message : this.collection){
message.sendCreateMessage(scriptSession,session);
}
}
scriptSession.setAttribute(SessionLabel.getCurrentSesionID(), httpSession.getId());
}

@SuppressWarnings(“deprecation”)
public final void sessionDestroyed(ScriptSessionEvent sSessionEvent) {//销毁一个ScriptSession时执行
ScriptSession scriptSession = sSessionEvent.getSession();
/*
Object username = (Object)scriptSession.getAttribute(SessionLabel.getCurrentScritpUserName());
if(username == null){
username = “”;
}
*/
for(IListenerMessage message : this.collection){
message.sessionDestroyed(sSessionEvent);
}
Collection<ScriptSession> collection = ServerContextFactory.get().getScriptSessionsByPage(scriptSession.getPage());
for(ScriptSession session : collection){
String scritpAttrID = (String)session.getAttribute(SessionLabel.getCurrentSesionID());
if( scritpAttrID != null){
for(IListenerMessage message : this.collection){
message.sendDestroyMessage(scriptSession,session);
}
}
}
}

public static class HttpSessionLabel{

private final String CurrentScriptSessionID = “DWR3.CurrScriptSession”;

private final String CurrentScritpUserName = “DWR.Chat.UserName”;

private final String CurrentSesionID = “DWR3.CurrSessionID”;

private final String CurrentPage = “DWR3.CurrPath”;

/**
* 获取当前SessionScript的在线页面
* @return currentPage
*/
public String getCurrentPage() {
return CurrentPage;
}

/**
* 获取Session中的当前ScriptSession的ID
* @return currentScriptSessionID
*/
public String getCurrentScriptSessionID() {
return CurrentScriptSessionID;
}

/**
* 获取当前用户名称
* @return currentScritpUserName
*/
public String getCurrentScritpUserName() {
return CurrentScritpUserName;
}

/**
* 获取ScriptSession中的HttpSessionID
* @return currentSesionID
*/
public String getCurrentSesionID() {
return CurrentSesionID;
}

}
}
[java] view plaincopy
package com.dwr;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* 在线ScriptSession(SSL)监听管理器.
* 在SSL中,每当DWR工厂在生成一个新的ScriptSession(SS)时,将被SSL捕获
* SSL对捕获的SS进行初始化赋值
* 其中在SS属性中的SessionLabel.CurrentSesionID赋予当前用户的SessinID
* 并在改用户的Session属性中的SessionLabel.CurrentScriptSessionID赋予当前的SSL
* 然后在SessionLabel.CurrentPage中赋予当前SS的操作界面地址
*
* 并且开始激活SSL插件中的sessionCreated方法
*
* 当
* @author 熊浩华 – ibmsz
*
* 2009-8-18:下午03:11:55-
*/
public class CustomScriptSessionListener implements ScriptSessionListener {

public static final HttpSessionLabel SessionLabel = new HttpSessionLabel();

private Collection<IListenerMessage> collection = null;

public CustomScriptSessionListener() throws Exception{
System.out.println(“开始构造SSL”);
collection = new Vector<IListenerMessage>();
SAXReader reader = new SAXReader();
Document document = reader.read(this.getClass().getResource(“ScriptSessionListener.xml”));
Element rootElement = document.getRootElement();
Iterator it = rootElement.elementIterator(“listener”);
while(it.hasNext() && it != null){
Element element = (Element)it.next();
String classPath = element.getTextTrim();
if(classPath == null || classPath.trim().equals(“”)){
continue;
}
Class cls = Class.forName(classPath);
Object object = cls.newInstance();
if(object instanceof IListenerMessage){
this.collection.add((IListenerMessage)object);
}
}
}

@SuppressWarnings(“deprecation”)
public final void sessionCreated(ScriptSessionEvent sSessionEvent) {
// System.out.println(“创建新的ScriptSession时执行”);
ScriptSession scriptSession = sSessionEvent.getSession(); //获取新创建的SS
WebContext webContext = WebContextFactory.get();
HttpServletRequest httpServletRequest = webContext.getHttpServletRequest();
HttpSession httpSession = httpServletRequest.getSession(); //获取构造SS的用户的HttpSession
ScriptSession currSession = (ScriptSession)httpSession.getAttribute(SessionLabel.getCurrentScriptSessionID());
if(currSession != null){
currSession.invalidate();
}
for(IListenerMessage message : this.collection){
message.sessionCreated(sSessionEvent);
}
httpSession.setAttribute(“DWR3.CurrPath”, scriptSession.getPage());
httpSession.setAttribute(“DWR3.CurrScriptSession”, scriptSession);
Collection<ScriptSession> sSCollection = webContext.getScriptSessionsByPage(scriptSession.getPage());
for(ScriptSession session : sSCollection){
if(session.getAttribute(SessionLabel.getCurrentSesionID()) == null){
continue;
}
for(IListenerMessage message : this.collection){
message.sendCreateMessage(scriptSession,session);
}
}
scriptSession.setAttribute(SessionLabel.getCurrentSesionID(), httpSession.getId());
}

@SuppressWarnings(“deprecation”)
public final void sessionDestroyed(ScriptSessionEvent sSessionEvent) {//销毁一个ScriptSession时执行
ScriptSession scriptSession = sSessionEvent.getSession();
/*
Object username = (Object)scriptSession.getAttribute(SessionLabel.getCurrentScritpUserName());
if(username == null){
username = “”;
}
*/
for(IListenerMessage message : this.collection){
message.sessionDestroyed(sSessionEvent);
}
Collection<ScriptSession> collection = ServerContextFactory.get().getScriptSessionsByPage(scriptSession.getPage());
for(ScriptSession session : collection){
String scritpAttrID = (String)session.getAttribute(SessionLabel.getCurrentSesionID());
if( scritpAttrID != null){
for(IListenerMessage message : this.collection){
message.sendDestroyMessage(scriptSession,session);
}
}
}
}

public static class HttpSessionLabel{

private final String CurrentScriptSessionID = “DWR3.CurrScriptSession”;

private final String CurrentScritpUserName = “DWR.Chat.UserName”;

private final String CurrentSesionID = “DWR3.CurrSessionID”;

private final String CurrentPage = “DWR3.CurrPath”;

/**
* 获取当前SessionScript的在线页面
* @return currentPage
*/
public String getCurrentPage() {
return CurrentPage;
}

/**
* 获取Session中的当前ScriptSession的ID
* @return currentScriptSessionID
*/
public String getCurrentScriptSessionID() {
return CurrentScriptSessionID;
}

/**
* 获取当前用户名称
* @return currentScritpUserName
*/
public String getCurrentScritpUserName() {
return CurrentScritpUserName;
}

/**
* 获取ScriptSession中的HttpSessionID
* @return currentSesionID
*/
public String getCurrentSesionID() {
return CurrentSesionID;
}

}
}

以上代码是从一个通过DWR实现的及时在线聊天系统中抽取出来的ScriptSession监听器.

红色标注部分为管理SS的程序段