最近开发项目,碰到跟其他团队合作开发,虽然同为java,但是基础架构完全不同,为了避免冲突,我们采用同一web容器,部署不同的服务,共享session的机制,达到散文的精髓:形散神不散。
首先看tomcat配置,打开conf/server.xml,找到Host节点,增加两个Context节点如下:
<Context path="/master" docBase="master" reloadable="true" crossContext="true"></Context> <Context path="/slave" docBase="slave" reloadable="true" crossContext="true"></Context>
其中master是主服务,包含用户登录、退出模块,slave是一个小功能模块,需要从session中获取登录用户信息。
关键配置在于 crossContext="true"
master的登录过滤器中加入如下代码:
long tm = System.currentTimeMillis();
Cookie cookie = new Cookie("__luid",Long.toString( tm ));
cookie.setPath("/");
cookie.setMaxAge(-1);
response.addCookie(cookie);
Map<Long,String> userMap = null;
try{
userMap = (Map) session.getServletContext().getAttribute("userMap");
}catch (Exception e){
userMap = new HashMap<Long, String>();
session.getServletContext().setAttribute("userMap",userMap);
}
userMap.put(tm,ppUser.getUserid());slave过滤器中调用如下方法:
private Integer getCrossUserid(HttpServletRequest request) {
try{
Cookie cookie = getCookie(request,"__luid") ;
if(cookie==null) return null;
ServletContext context = request.getSession().getServletContext().getContext("/master");
if(context==null) return null;
Map<Long,Integer> userMap = null;
userMap = (Map)context.getAttribute("userMap");
if(userMap.size()>10000) clearUserMap(userMap);
long luid = Long.parseLong(cookie.getValue());
Integer iuserid = userMap.get(luid);
request.setAttribute(REQUEST_ATTR_USERID, iuserid);
return iuserid;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}原理如下:
主服务维护一个userMap,把当前登录用户数据插入到userMap,把userMap放到当前的ServletContext;
从服务读取主服务的ServletContext,获取到userMap,根据cookie数据获取到用户信息。
形散神不散:Tomcat 下多个虚拟目录共享session方法
原文地址:http://11030261.blog.51cto.com/11020261/1726727