最近开发项目,碰到跟其他团队合作开发,虽然同为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