tomcat共享多个web应用会话的实现方法
tomcat共享多个web应用会话的实现方法
问题
今天有位朋友问了个问题,大致是:tomcat下两个Javaweb,一个是商城,一个是直播,从商城登录后,再跳转到直播,发现处于非登录状态。
解决思路
- 将session抽出来成一个session服务,统一通过该服务操作session。
- tomcat内部用会话管理器获取会话时遍历所有context内的会话。
方案1
重写获取session方法即可。
方案2
找了源码发现已经支持类似遍历所有context内的会话的形式,首先获取session时,如果cressContext属性为true,则会在获取不到时尝试遍历所有context是否存在该sessionid,如果存在则在本context根据sessionid创建自己的session对象。
publicHttpSessiongetSession(booleancreate){ if(crossContext){ //Therecannotbeasessionifnocontexthasbeenassignedyet if(context==null) return(null); //Returnthecurrentsessionifitexistsandisvalid if(session!=null&&session.isValid()){ return(session.getSession()); } HttpSessionother=super.getSession(false); if(create&&(other==null)){ //Firstcreateasessioninthefirstcontext:theproblemis //thatthetoplevelrequestistheonlyonewhichcan //createthecookiesafely other=super.getSession(true); } if(other!=null){ SessionlocalSession=null; try{ localSession= context.getManager().findSession(other.getId()); if(localSession!=null&&!localSession.isValid()){ localSession=null; } }catch(IOExceptione){ //Ignore } if(localSession==null&&create){ localSession= context.getManager().createSession(other.getId()); } if(localSession!=null){ localSession.access(); session=localSession; returnsession.getSession(); } } returnnull; }else{ returnsuper.getSession(create); } }
context(web应用)获取跨应用session时通过类似下面操作获取:
request.getSession().getServletContext().getContext("/app2").getAttribute("att2");
这是因为request会根据cookies的sessionid获取到session对象,这时不会报找不到,因为前面已经根据其他sessionid创建了一个session对象,然后getContext操作会获取对应url的context,接着进行会话操作。
publicServletContextgetContext(Stringuri){ //Validatetheformatofthespecifiedargument if(uri==null||!uri.startsWith("/")){ returnnull; } Contextchild=null; try{ //Lookforanexactmatch Containerhost=context.getParent(); child=(Context)host.findChild(uri); //Non-runningcontextsshouldbeignored. if(child!=null&&!child.getState().isAvailable()){ child=null; } //Removeanyversioninformationandusethemapper if(child==null){ inti=uri.indexOf("##"); if(i>-1){ uri=uri.substring(0,i); } //Note:ThiscouldbemoreefficientwithadedicatedMapper //methodbutsuchanimplementationwouldrequiresome //refactoringoftheMappertoavoidcopy/pasteof //existingcode. MessageByteshostMB=MessageBytes.newInstance(); hostMB.setString(host.getName()); MessageBytespathMB=MessageBytes.newInstance(); pathMB.setString(uri); MappingDatamappingData=newMappingData(); ((Engine)host.getParent()).getService().findConnectors()[0].getMapper().map( hostMB,pathMB,null,mappingData); child=(Context)mappingData.context; } }catch(Throwablet){ ExceptionUtils.handleThrowable(t); returnnull; } if(child==null){ returnnull; } if(context.getCrossContext()){ //IfcrossContextisenabled,canalwaysreturnthecontext returnchild.getServletContext(); }elseif(child==context){ //Canstillreturnthecurrentcontext returncontext.getServletContext(); }else{ //Nothingtoreturn returnnull; } }
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家都对本站的支持!