当我们在使用DWR的反向AJax是,每次页面的刷新都会产生一个ScriptSession(SS),但是我们确无从对过期的SS进行即使的销毁,虽然可以通过在每个页面访问时,自动执行某个方法,来销毁那些当前用户的非有效SS,但是这样也使得我们在代码管理上带来非常麻烦的问题.
DWR3的诞生终于给我们提供了ScritpSessionLintener(SSL)接口
本文,主要讲解如何使用ScriptSession接口.
DWR支持在Web.XML当中,配置扩展.
* *
但是,经过几次的实验和摸索,SSL在当中配置后,管理器会进行有效构造,但是SS在创建和销毁时,并不会执行继承了ScriptSessionListner类的相关方法.(或许是我自己项目的问题.)
经过自己的研究发现,在ScriptSessionManager类中,包含了AddScriptSessionListener方()法.这样给使用SSL带来了方便
我们只需要在Web.XML文件中配置一个自定义的ScrptSessionManager
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存在于内存当中,使得我们的程序更加高效.
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 Collectioncollection = null; public CustomScriptSessionListener() throws Exception{ System.out.println("开始构造SSL"); collection = new Vector (); 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 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 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的程序段
全案例源代码下载