最近在开发项目遇到需要多个项目共享session,在网上找了方法,实际测试发现有问题,下面将正确的方式写出来,供大家参考。
一般网络上能找到的好像都是从一个人的blog中copy的,都有相同的问题,让我们先来看看网上能找到的共享实现方式
有时我们会遇到一个大点的项目,为了方便实现有些功能,我们会把项目拆成不同的独立web项目。
但我们在管理这些项目时,只有一个登陆口,然后在其他项目取session来实现身份的验证。
--------------------------以下部分来自网络,是我筛选的认为写的比较明白的-------------------
1、配置tomcat下 conf/server.xml文件,在<Host></Hoser>配置如下:
<Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <!-- aa 和bb 为两个不同的web项目 --> <Context path="/aa" reloadable="true" crossContext="true" /> <Context path="/bb" reloadable="true" crossContext="true"/> </Host>
2、 在 aa项目存入session
session.setAttribute("user",new Date().toString()+"weiqingli"); ServletContext ContextA =session.getServletContext(); ContextA.setAttribute("session", session);
3、在bb 项目取出 session
HttpSession session1 =request.getSession(); ServletContext Context = session1.getServletContext(); ServletContext Context1= Context.getContext("/aa"); if(Context1 !=null && !Context1.equals("")){ HttpSession sess =(HttpSession)Context1.getAttribute("session"); out.println(sess.getAttribute("user")); }
大家可能很容易看得出这个是单向传的session,其实要实现双向,将上面的程序反写就可以实现从bb存入,aa取出了。
----------------------------网络截取部分完成--------------------------------
如果你在项目中真的这样用,你会发现,只有一个用户能登录,还有其他的一些问题。
正确的写法应该是这样的,首先tomcat的配置文件, crossContext="true" 这部分的含义是可以调用另外一个WEB应用程序 通过ServletContext.getContext() 获得ServletContext 然后再调用其getattribute() 得到你要的对象。只有这样是不够的,还需要加上 sessionCookiePath="/" 这部分的含义是 Session Cookie的位置在根目录“/”这样多个应用可以互相交互 。注意如果 sessionCookiePath="/" 你不这样写,很有可能你每次获得的sessionID都不一样。
然后我们看看来自网络部分其他的问题,关键在aa项目存入session的时候,有这样一句话
ContextA.setAttribute("session", session);
这句话就是每次都覆盖 "session" 这样在 ContextA 服务器中只有这样一个session 。如果你用session保存登录用户的话,那只能有一个人处于登录状态,就是最后登录的那个人。
下面给出正确的写法。
首先是tomcat配置部分:
<Host name="localhost" appBase="f:/www" unpackWARs="true" autoDeploy="true" crossContext="true"> <Context path="/" docBase="" debug="0" reloadable="true" crossContext="true" sessionCookiePath="/" /> <Context path="/testA" docBase="testA.war" debug="0" reloadable="true" crossContext="true" sessionCookiePath="/" /> <Context path="/testB" docBase="testB.war" debug="0" reloadable="true" crossContext="true" sessionCookiePath="/" />
然后在testA项目里面存入session
session.setAttribute("user", "555=+++====||"); session.setAttribute("accountId", a); ServletContext context = session.getServletContext(); context.setAttribute(session.getId(), session); // 注意这里,要传递sessionID过去
之后是在testB项目里面获得session
ServletContext Context = session.getServletContext().getContext("/testA");// 这里面传递的项目A的路径
if (Context == null) { return "testA Context is null ~!~!~!~!~!"+ "session.getId=" + session.getId(); } if (Context.getAttribute(session.getId()) == null) { return "no testA Context session get~!!!!!!!"+ "session.getId=" + session.getId(); } HttpSession sessionUser = (HttpSession) Context.getAttribute(session.getId());
这样的话,项目testA存储的session在项目testB中就能够获得了,支持多用户。