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;
}
}
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家都对本站的支持!