南强小屋 Design By 杰米
tomcat共享多个web应用会话的实现方法
问题
今天有位朋友问了个问题,大致是:tomcat下两个Java web,一个是商城,一个是直播,从商城登录后,再跳转到直播,发现处于非登录状态。
解决思路
- 将session抽出来成一个session服务,统一通过该服务操作session。
- tomcat内部用会话管理器获取会话时遍历所有context内的会话。
方案1
重写获取session方法即可。
方案2
找了源码发现已经支持类似遍历所有context内的会话的形式,首先获取session时,如果cressContext属性为true,则会在获取不到时尝试遍历所有context是否存在该sessionid,如果存在则在本context根据sessionid创建自己的session对象。
public HttpSession getSession(boolean create) { if (crossContext) { // There cannot be a session if no context has been assigned yet if (context == null) return (null); // Return the current session if it exists and is valid if (session != null && session.isValid()) { return (session.getSession()); } HttpSession other = super.getSession(false); if (create && (other == null)) { // First create a session in the first context: the problem is // that the top level request is the only one which can // create the cookie safely other = super.getSession(true); } if (other != null) { Session localSession = null; try { localSession = context.getManager().findSession(other.getId()); if (localSession != null && !localSession.isValid()) { localSession = null; } } catch (IOException e) { // Ignore } if (localSession == null && create) { localSession = context.getManager().createSession(other.getId()); } if (localSession != null) { localSession.access(); session = localSession; return session.getSession(); } } return null; } else { return super.getSession(create); } }
context(web应用)获取跨应用session时通过类似下面操作获取:
request.getSession().getServletContext().getContext("/app2").getAttribute("att2");
这是因为request会根据cookies的sessionid获取到session对象,这时不会报找不到,因为前面已经根据其他sessionid创建了一个session对象,然后getContext操作会获取对应url的context,接着进行会话操作。
public ServletContext getContext(String uri) { // Validate the format of the specified argument if (uri == null || !uri.startsWith("/")) { return null; } Context child = null; try { // Look for an exact match Container host = context.getParent(); child = (Context) host.findChild(uri); // Non-running contexts should be ignored. if (child != null && !child.getState().isAvailable()) { child = null; } // Remove any version information and use the mapper if (child == null) { int i = uri.indexOf("##"); if (i > -1) { uri = uri.substring(0, i); } // Note: This could be more efficient with a dedicated Mapper // method but such an implementation would require some // refactoring of the Mapper to avoid copy/paste of // existing code. MessageBytes hostMB = MessageBytes.newInstance(); hostMB.setString(host.getName()); MessageBytes pathMB = MessageBytes.newInstance(); pathMB.setString(uri); MappingData mappingData = new MappingData(); ((Engine) host.getParent()).getService().findConnectors()[0].getMapper().map( hostMB, pathMB, null, mappingData); child = (Context) mappingData.context; } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); return null; } if (child == null) { return null; } if (context.getCrossContext()) { // If crossContext is enabled, can always return the context return child.getServletContext(); } else if (child == context) { // Can still return the current context return context.getServletContext(); } else { // Nothing to return return null; } }
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家都对本站的支持!
南强小屋 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
南强小屋 Design By 杰米
暂无tomcat共享多个web应用会话的实现方法的评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?