session共享问题(一)----同一tomcat多个应用session问题
2016-09-13 11:31
363 查看
问题描述:
最近一直在研究session共享的问题,现在分享一下我最近对这个问题的理解。这需要分不同情况下,不同的项目部署情况对应的解决方式也不一样。今天我讲的是一个简单的情况(一般也只有小型的项目才会有这种情况,现在大项目都用到集群,分布式)------------同一个tomcat下多个应用之间的session共享情况
应用场景:
现在项目都模块化,一个大项目分成多个小项目,而且用户登录注册独立成一个小项目,这时候如果其它小项目要从用户项目中拿用户项目中拿session数据,这时候就要面临同一个tomcat多个应用之间的session共享问题了
解决思路:
1、直接将session数据放到公共地方,redis或数据库或 cookies(小项目可以这样做)
2、直接session共享,从用户中心拿(只使用同一个tomcat)
解决问题前你要了解一下情况:
同一台服务器, 安装两个tomcat ,端口不一样, 姑且分别称为tomcat1 和 tomcat2, 在两个tomcat下分别都部署了A和B两个项目
同一个浏览器访问同一个tomcat的不同项目: 访问tomcat1(tomcat2)的A并登陆, 再访问tomcat1(tomcat2)的B , 测试结果两个项目的访问互不干扰;
同一个浏览器访问不同tomcat的不同项目: 访问tomcat1的A并登陆, 再访问tomcat2的B, 测试结果两个项目的访问互不干扰;
同一个浏览器访问不同tomcat的相同项目: 访问tomcat1的A(B)项目并登陆, 再访问tomcat2的A(B), 测试结果访问tomcat2的A(B)项目之后, 造成了sessionID的覆盖,使之前登录过的tomcat1的A(B)项目的session失效;
解决方案(主要讲第二种):
1、修改tomcat的server.xml文件
每一个web应用程序都有唯一一个ServletContext实例对象,被该web应用下面的每一个servlet共享。通过修改tomcat的server.xml,使不同web应用的ServletContext可以互相访问。然后,用ServletContext的setAttribute()方法把session存入ServletContext中,在另一个web程序就可以用getAttribute()方法取得传递过来的session。
server.xml文件修改如下:
crossContext属性的意思是:如果设置为true,你可以通过ServletContext.getContext() 调用另外一个WEB应用程序,获得ServletContext 然后再调用其getAttribute() 得到你要的对象。
Java代码如下:
WebappA:
WebappB:
总结:
其实这种项目部署的情况一般不太会有,一般大公司都是集群部署的。小公司的项目还是有可能用到这种情况。
如有不错的地方尽情的提,哈哈
最近一直在研究session共享的问题,现在分享一下我最近对这个问题的理解。这需要分不同情况下,不同的项目部署情况对应的解决方式也不一样。今天我讲的是一个简单的情况(一般也只有小型的项目才会有这种情况,现在大项目都用到集群,分布式)------------同一个tomcat下多个应用之间的session共享情况
应用场景:
现在项目都模块化,一个大项目分成多个小项目,而且用户登录注册独立成一个小项目,这时候如果其它小项目要从用户项目中拿用户项目中拿session数据,这时候就要面临同一个tomcat多个应用之间的session共享问题了
解决思路:
1、直接将session数据放到公共地方,redis或数据库或 cookies(小项目可以这样做)
2、直接session共享,从用户中心拿(只使用同一个tomcat)
解决问题前你要了解一下情况:
同一台服务器, 安装两个tomcat ,端口不一样, 姑且分别称为tomcat1 和 tomcat2, 在两个tomcat下分别都部署了A和B两个项目
同一个浏览器访问同一个tomcat的不同项目: 访问tomcat1(tomcat2)的A并登陆, 再访问tomcat1(tomcat2)的B , 测试结果两个项目的访问互不干扰;
同一个浏览器访问不同tomcat的不同项目: 访问tomcat1的A并登陆, 再访问tomcat2的B, 测试结果两个项目的访问互不干扰;
同一个浏览器访问不同tomcat的相同项目: 访问tomcat1的A(B)项目并登陆, 再访问tomcat2的A(B), 测试结果访问tomcat2的A(B)项目之后, 造成了sessionID的覆盖,使之前登录过的tomcat1的A(B)项目的session失效;
解决方案(主要讲第二种):
1、修改tomcat的server.xml文件
每一个web应用程序都有唯一一个ServletContext实例对象,被该web应用下面的每一个servlet共享。通过修改tomcat的server.xml,使不同web应用的ServletContext可以互相访问。然后,用ServletContext的setAttribute()方法把session存入ServletContext中,在另一个web程序就可以用getAttribute()方法取得传递过来的session。
server.xml文件修改如下:
<Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"> <Context path="/WebappA" debug="9" reloadable="true" crossContext="true"/> //WebappA为项目名,crossContext="true" //是关键 <Context path="/WebappB" debug="9" reloadable="true" crossContext="true"/> </Host>
crossContext属性的意思是:如果设置为true,你可以通过ServletContext.getContext() 调用另外一个WEB应用程序,获得ServletContext 然后再调用其getAttribute() 得到你要的对象。
Java代码如下:
WebappA:
HttpSession session = request.getSession(); session.setAttribute("userId", "test"); ServletContext ContextA =session .getServletContext(); ContextA.setAttribute("session", session );
WebappB:
HttpSession sessionB = request.getSession(); ServletContext ContextB = sessionB.getServletContext(); ServletContext ContextA= ContextB.getContext("/WebappA");// 这里面传递的是 WebappA的虚拟路径 HttpSession sessionA =(HttpSession)ContextA.getAttribute("session"); System.out.println("userId: "+sessionA.getAttribute("userId"));
总结:
其实这种项目部署的情况一般不太会有,一般大公司都是集群部署的。小公司的项目还是有可能用到这种情况。
如有不错的地方尽情的提,哈哈
相关文章推荐
- tomcat 安装
- 远程调试配置 修改tomcat内存
- Tomcat之Windows环境下配置多个服务器
- Tomcat-基础篇
- nginx 的动静分离配置(tomcat)
- linux tomcat安装
- 如何优化tomcat配置(从内存、并发、缓存4个方面)优化
- javaweb环境配置:java,tomcat,maven
- windows_TomCat配置
- 为什么eclipse中启动tomcat后,浏览器中出现404?
- nginx+tomcat实现负载均衡
- Eclipse启动Tomcat时报错:严重: Error configuring application listener of class
- jvm实例,tomcat容器,spring容器,在内存中的关系
- Centos搭建xwiki+mysql+tomcat
- tomcat集群和负载均衡
- Java后端WebSocket的Tomcat实现 html5 WebSocket 实时聊天
- tomcat & spring session管理
- Apache Tomcat开机后台启动
- Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds. If the server require
- Tomcat(8080、8009、8005端口占用)无法启动问题解决