跨Session通信的解决方案

跨Session通信的解决方案

            HttpSession 大家都很熟悉,但在使用过程中,它是将每一个用户的请求链组成一个与其他用户请求链相隔绝的会话,这也就意味着通常情况下,用户A无法访问用户B的会话, 它只能用它自己的请求取得它自己的会话: HttpServletRequest.getSession()来获得。但通过使用Servlet厂商API,我们是可以做到让各个会话之间互相访问.
  下面 简单介绍下厂商API,  在SUN设计出J2EE规范的时候,它的实现分为了2部分,一部分是由厂商实现,被成为厂商API,比如Weblogic对 EJB的实现等, 另外一部分是用户API,这就需要我们自己去实现, 当然用户API要运行在厂商API的基础之上才可以, 通常情况下,一个典型的web应用,其实是由Apache和用户自己共同完成的.
  对于一个Web应用,厂商实现了大部分接口,比如HttpServletRequest接口,Connection接口等,但用户通常并没有去管这个 接口是如何实现的,大家都知道直接使用JDBC的java.sql.Connection接口,但很少有人关注它的实现,当然关注它的人大多数都是 JDBC 驱动程序的开发人员. 现在基本理论到此结束,开始论证本文论点.
  在Web容器里(厂商API), 有javax.servlet.ServletRequestListener,它主要对请求进行监听,HttpSessionListener主要对会话进行监听,处理会话创建事件,会话销毁时间等,
如果我们能在某个地方保存所有活跃状态的HttpSession对象的引用,那么我们就可以对所有的客户会话进行随心所欲的操作.使得本会话向其他会话读写数据成为可能.
下面举例子说明:
1. 建立缓存,专门存放用户Session的引用: Cache.java
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
public class Cache {
    public static Map<String,HttpSession> cache = new HashMap<String,HttpSession>();
}

2.实现监听接口:

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class TestListener implements ServletRequestListener,HttpSessionListener {
   
        //private static Map <String,HttpSession> cache = new HashMap<String,HttpSession>();
        private String clientIP = "127.0.0.1";
       
        public void requestDestroyed(ServletRequestEvent rre) {
                // TODO Auto-generated method stub
                System.out.println("Distroy");
        }

        public void requestInitialized(ServletRequestEvent rre) {
                // TODO Auto-generated method stub
                System.out.println("Init");
                this.clientIP = rre.getServletRequest().getRemoteAddr();
        }

        public void sessionCreated(HttpSessionEvent se) {
                // TODO Auto-generated method stub
                System.out.println("AA");
                Cache.cache.put(this.clientIP, se.getSession());
                System.out.println("添加到cache");
        }

        public void sessionDestroyed(HttpSessionEvent se) {
                // TODO Auto-generated method stub
                System.out.println("BB");
                                Cache.cache.remove(se.getSession());
        }

}

3.注册监听器: 在web.xml里加:
<listener>
    <listener-class>TestListener</listener-class>
  </listener>

4.测试:
在任意Servlet或者JSP里, HttpSession session = Cache.cache.get("客户端IP地址");
取得对该客户端session的引用,剩下的就是读写操作了,

备注: 该方法迫不得已的时候在用,另外保护好自己的Cache类,避免被他人非法引用,当然你也可以用这个办法取黑别人.



        一般Session级别的数据共享用的比较少,但如果确实要共享用户数据,但又不是对用户数据 的全部共享,这样就没有必要使用ServletContext(application), 一个会话会在过期的时候被自动销毁掉,而ServletContext则不会,除非关闭服务器,假设你要做一个在线聊天,A用户要发送消息给B用户,中间 可能有文件传输等,这样服务器就不能用ServletContext,否则对大量图片的缓存会造成很严重的后果,而用这种方式就比较好,根据A发送的消息 (包含对方地址 ),服务器直接取得目标地址的Session把数据写进去,而每个客户只需要从自己的session里读取数据,而服务器仅仅作为一个路由器的功能,而不 是一个缓存器,这样效率自然就会很高.
        当然,以上方法,还可以被加工成一个木马,它可以访问肉鸡上的所有Http会话,当然很多信息可能很有价值,不妨试试...


原文引自:
http://bbs.star-bbs.net/viewthread.php?tid=71527
posted @ 2008-01-31 09:42  简单飞扬-  阅读(571)  评论(0编辑  收藏  举报