tomcat如何共享多个web应用会话

原创 2017年02月22日 08:14:29

问题

今天有位朋友问了个问题,大致是:tomcat下两个Java web,一个是商城,一个是直播,从商城登录后,再跳转到直播,发现处于非登录状态。

解决思路

  1. 将session抽出来成一个session服务,统一通过该服务操作session。
  2. tomcat内部用会话管理器获取会话时遍历所有context内的会话。

方案1

重写获取session方法即可。

方案2

找了源码发现已经支持类似遍历所有context内的会话的形式,首先获取session时,如果cressContext属性为true,则会在获取不到时尝试遍历所有context是否存在该sessionid,如果存在则在本context根据sessionid创建自己的session对象。

 public HttpSession getSession(boolean create) {

        if (crossContext) {

            // There cannot be a session if no context has been assigned yet
            if (context == null)
                return (null);

            // Return the current session if it exists and is valid
            if (session != null && session.isValid()) {
                return (session.getSession());
            }

            HttpSession other = super.getSession(false);
            if (create && (other == null)) {
                // First create a session in the first context: the problem is
                // that the top level request is the only one which can 
                // create the cookie safely
                other = super.getSession(true);
            }
            if (other != null) {
                Session localSession = null;
                try {
                    localSession =
                        context.getManager().findSession(other.getId());
                    if (localSession != null && !localSession.isValid()) {
                        localSession = null;
                    }
                } catch (IOException e) {
                    // Ignore
                }
                if (localSession == null && create) {
                    localSession = 
                        context.getManager().createSession(other.getId());
                }
                if (localSession != null) {
                    localSession.access();
                    session = localSession;
                    return session.getSession();
                }
            }
            return null;

        } else {
            return super.getSession(create);
        }

    }

context(web应用)获取跨应用session时通过类似下面操作获取:

request.getSession().getServletContext().getContext("/app2").getAttribute("att2"); 

这是因为request会根据cookies的sessionid获取到session对象,这时不会报找不到,因为前面已经根据其他sessionid创建了一个session对象,然后getContext操作会获取对应url的context,接着进行会话操作。

public ServletContext getContext(String uri) {

        // Validate the format of the specified argument
        if (uri == null || !uri.startsWith("/")) {
            return null;
        }

        Context child = null;
        try {
            // Look for an exact match
            Container host = context.getParent();
            child = (Context) host.findChild(uri);

            // Non-running contexts should be ignored.
            if (child != null && !child.getState().isAvailable()) {
                child = null;
            }

            // Remove any version information and use the mapper
            if (child == null) {
                int i = uri.indexOf("##");
                if (i > -1) {
                    uri = uri.substring(0, i);
                }
                // Note: This could be more efficient with a dedicated Mapper
                //       method but such an implementation would require some
                //       refactoring of the Mapper to avoid copy/paste of
                //       existing code.
                MessageBytes hostMB = MessageBytes.newInstance();
                hostMB.setString(host.getName());

                MessageBytes pathMB = MessageBytes.newInstance();
                pathMB.setString(uri);

                MappingData mappingData = new MappingData();
                ((Engine) host.getParent()).getService().findConnectors()[0].getMapper().map(
                        hostMB, pathMB, null, mappingData);
                child = (Context) mappingData.context;
            }
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            return null;
        }

        if (child == null) {
            return null;
        }

        if (context.getCrossContext()) {
            // If crossContext is enabled, can always return the context
            return child.getServletContext();
        } else if (child == context) {
            // Can still return the current context
            return context.getServletContext();
        } else {
            // Nothing to return
            return null;
        }
    }

点击订购作者《Tomcat内核设计剖析》

博主的书

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

tomcat会话之持久化会话管理器

前面提到的标准会话管理器已经提供了基础的会话管理功能,但在持久化方面做得还是不够,或者说在某些情景下无法满足要求,例如把会话以文件或数据库形式存储到存储介质中,这些都是标准会话管理器无法做到的,于是另...

Tomcat会话管理元素Manager五种对象介绍

1、StandardManager      如果不配置Tomcat以使用不同的管理器,则这一管理器就是默认的会话管理器。这是在Tomcat正运行时在内存中处理会话的非集群实现。  ...

tomcat集群及seeion共享

tomcat集群 分类: 中间件2011-07-07 16:19815人阅读评论(3)收藏举报 对于WEB应用集群的技术实现而言,最大的难点就是如何能在集群中的多个节点之间保持数据...

tomcat集群机制剖析-tomcat的session会话共享方式

为什么要使用集群? 为什么要使用集群?主要有两方面原因:一是对于一些核心系统要求长期不能中断服务,为了提供高可用性我们需要由多台机器组成的集群;另外一方面,随着访问量越来越大且业务逻辑越来越复杂...

多个tomcat 共享一个应用程序目录

第一种方式,把应用放到一个公共目录,修改server.xml中配置 的相对目录.如果没有此项,默认 为/webapps. 它将匹配请求和自己的Context的路径,并把请求转交给对应的Context...

tomcat配置多个虚拟host,访问不同的web项目

想要在一个tomcat下访问两个web项目时,可以通过添加虚拟host的方式来解决。       详细步骤如下:        1、将两个项目打包放入tomcat的webapps目录下;...

tomcat配置多个web网站的配置详解

假如只有一台服务器,需要配置多个web网站(端口不同我还没试),该怎么样配置tomcat呢,其实很简单,只需要将tomcat 下面的 server.xml  中增加两个甚至是多个…… 标签即可, 标签...

web.xml 中的listener、 filter、servlet 加载顺序及其详解

一、概述 1、启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取和两个结点。  2、紧急着,容创建一个ServletContext(servlet上下文),这个w...

Java GC基本算法

1、JVM内存组成结构 JVM内存结构由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示: 1)堆 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)