高效管理DWR中的ScriptSession,ScriptSessionLintener

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

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

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

 

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

Xml代码 复制代码
  1. <init-param>  
  2.    <param-name>*</param-name>  
  3.    <param-value>*</param-value>  
  4. </init-param>  

 

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

 

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

 

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

 

Java代码 复制代码
  1. public class CustomScriptSessionManager extends org.directwebremoting.impl.DefaultScriptSessionManager  {   
  2.   
  3.  public CustomScriptSessionManager(){   
  4.   try {   
  5.    this.addScriptSessionListener(new CustomScriptSessionListener());   
  6.   } catch (Exception e) {   
  7.    e.printStackTrace();   
  8.   }   
  9.  }   
  10. }  
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代码 复制代码
  1. package com.dwr;   
  2.   
  3. import java.util.Collection;   
  4. import java.util.Iterator;   
  5. import java.util.Vector;   
  6.   
  7. import javax.servlet.http.HttpServletRequest;   
  8. import javax.servlet.http.HttpSession;   
  9.   
  10. import org.directwebremoting.ScriptSession;   
  11. import org.directwebremoting.ServerContextFactory;   
  12. import org.directwebremoting.WebContext;   
  13. import org.directwebremoting.WebContextFactory;   
  14. import org.directwebremoting.event.ScriptSessionEvent;   
  15. import org.directwebremoting.event.ScriptSessionListener;   
  16. import org.dom4j.Document;   
  17. import org.dom4j.Element;   
  18. import org.dom4j.io.SAXReader;   
  19.   
  20.   
  21. /**  
  22.  * 在线ScriptSession(SSL)监听管理器.  
  23.  * 在SSL中,每当DWR工厂在生成一个新的ScriptSession(SS)时,将被SSL捕获  
  24.  * SSL对捕获的SS进行初始化赋值  
  25.  * 其中在SS属性中的SessionLabel.CurrentSesionID赋予当前用户的SessinID  
  26.  * 并在改用户的Session属性中的SessionLabel.CurrentScriptSessionID赋予当前的SSL  
  27.  * 然后在SessionLabel.CurrentPage中赋予当前SS的操作界面地址  
  28.  *   
  29.  * 并且开始激活SSL插件中的sessionCreated方法  
  30.  *   
  31.  * 当  
  32.  * @author 熊浩华 - ibmsz  
  33.  *  
  34.  * 2009-8-18:下午03:11:55-  
  35.  */  
  36. public class CustomScriptSessionListener  implements ScriptSessionListener  {   
  37.   
  38.  public static final HttpSessionLabel SessionLabel = new HttpSessionLabel();   
  39.     
  40.  private Collection<IListenerMessage> collection = null;   
  41.     
  42.  public CustomScriptSessionListener() throws Exception{   
  43.   System.out.println("开始构造SSL");   
  44.   collection = new Vector<IListenerMessage>();   
  45.   SAXReader reader = new SAXReader();   
  46.   Document document = reader.read(this.getClass().getResource("ScriptSessionListener.xml"));   
  47.   Element rootElement = document.getRootElement();   
  48.   Iterator it = rootElement.elementIterator("listener");   
  49.   while(it.hasNext() && it != null){   
  50.    Element element = (Element)it.next();   
  51.    String classPath = element.getTextTrim();   
  52.    if(classPath == null || classPath.trim().equals("")){   
  53.     continue;   
  54.    }   
  55.    Class cls = Class.forName(classPath);   
  56.    Object object = cls.newInstance();   
  57.    if(object instanceof IListenerMessage){   
  58.     this.collection.add((IListenerMessage)object);   
  59.    }   
  60.   }   
  61.  }   
  62.     
  63.     
  64.     
  65.  @SuppressWarnings("deprecation")   
  66.  public final void sessionCreated(ScriptSessionEvent sSessionEvent) {   
  67. //  System.out.println("创建新的ScriptSession时执行");   
  68.   ScriptSession scriptSession = sSessionEvent.getSession(); //获取新创建的SS   
  69.   WebContext webContext = WebContextFactory.get();   
  70.   HttpServletRequest httpServletRequest = webContext.getHttpServletRequest();   
  71.   HttpSession httpSession = httpServletRequest.getSession(); //获取构造SS的用户的HttpSession   
  72.   ScriptSession currSession = (ScriptSession)httpSession.getAttribute(SessionLabel.getCurrentScriptSessionID());   
  73.   if(currSession != null){   
  74.    currSession.invalidate();   
  75.   }   
  76.   for(IListenerMessage message : this.collection){   
  77.    message.sessionCreated(sSessionEvent);   
  78.   }   
  79.   httpSession.setAttribute("DWR3.CurrPath", scriptSession.getPage());   
  80.   httpSession.setAttribute("DWR3.CurrScriptSession", scriptSession);   
  81.   Collection<ScriptSession> sSCollection =  webContext.getScriptSessionsByPage(scriptSession.getPage());   
  82.   for(ScriptSession session : sSCollection){   
  83.    if(session.getAttribute(SessionLabel.getCurrentSesionID()) == null){   
  84.     continue;   
  85.    }   
  86.    for(IListenerMessage message : this.collection){   
  87.     message.sendCreateMessage(scriptSession,session);   
  88.    }   
  89.   }   
  90.   scriptSession.setAttribute(SessionLabel.getCurrentSesionID(), httpSession.getId());   
  91.  }   
  92.   
  93.  @SuppressWarnings("deprecation")   
  94.  public final void sessionDestroyed(ScriptSessionEvent sSessionEvent) {//销毁一个ScriptSession时执行   
  95.   ScriptSession scriptSession = sSessionEvent.getSession();   
  96.   /*  
  97.   Object username = (Object)scriptSession.getAttribute(SessionLabel.getCurrentScritpUserName());  
  98.   if(username == null){  
  99.    username = "";  
  100.   }  
  101.   */  
  102.   for(IListenerMessage message : this.collection){   
  103.    message.sessionDestroyed(sSessionEvent);   
  104.   }   
  105.   Collection<ScriptSession> collection = ServerContextFactory.get().getScriptSessionsByPage(scriptSession.getPage());   
  106.   for(ScriptSession session : collection){   
  107.    String scritpAttrID = (String)session.getAttribute(SessionLabel.getCurrentSesionID());   
  108.    if( scritpAttrID != null){   
  109.     for(IListenerMessage message : this.collection){   
  110.      message.sendDestroyMessage(scriptSession,session);   
  111.     }   
  112.    }   
  113.   }   
  114.  }   
  115.   
  116.  public static class HttpSessionLabel{   
  117.      
  118.   private final String CurrentScriptSessionID = "DWR3.CurrScriptSession";   
  119.      
  120.   private final String CurrentScritpUserName = "DWR.Chat.UserName";   
  121.      
  122.   private final String CurrentSesionID = "DWR3.CurrSessionID";   
  123.   
  124.   private final String CurrentPage = "DWR3.CurrPath";   
  125.      
  126.   /**  
  127.    * 获取当前SessionScript的在线页面  
  128.    * @return currentPage  
  129.    */  
  130.   public String getCurrentPage() {   
  131.    return CurrentPage;   
  132.   }   
  133.   
  134.   /**  
  135.    * 获取Session中的当前ScriptSession的ID  
  136.    * @return currentScriptSessionID  
  137.    */  
  138.   public String getCurrentScriptSessionID() {   
  139.    return CurrentScriptSessionID;   
  140.   }   
  141.   
  142.   /**  
  143.    * 获取当前用户名称  
  144.    * @return currentScritpUserName  
  145.    */  
  146.   public String getCurrentScritpUserName() {   
  147.    return CurrentScritpUserName;   
  148.   }   
  149.   
  150.   /**  
  151.    * 获取ScriptSession中的HttpSessionID  
  152.    * @return currentSesionID  
  153.    */  
  154.   public String getCurrentSesionID() {   
  155.    return CurrentSesionID;   
  156.   }   
  157.      
  158.  }   
  159. }  
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的程序段

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值