单浏览器支持多session解决方案

当我们一个客户端请求服务时,如果是第一次请求该服务,服务容器(tomcat,jetty,jboss)等会创建一个会话session并且把sessionid通过响应头下发给客户端,客户端后续在访问这个域下的任何服务,会通过请求头cookie把sessionID提交到服务容器,服务容器由此来判断是否是同一会话

以上是我们原始的session原理,在大部分情况下原始的session是没有问题的。

如果现在有一种场景 我们需要在同一浏览器种多账号同时在线,这种场景传统模式的session就不太适用此业务场景

这时候一种新型的session架构模式就登场了-spring-session

先说下spring-session支持功能

1.轻易把session存储到第三方存储容器,框架提供了redis、jvm的map、mongo、gemfire、hazelcast、jdbc等多种存储session的容器的方式。

2.同一个浏览器同一个网站,支持多个session问题。

3.Restful API,不依赖于cookie。可通过header来传递jessionID

4.WebSocket和spring-session结合,同步生命周期管理

spring-session 框架内部分析



spring-session 几个核心接口如下:

Session:这个接口定义了session基本功能

public interface Session {


    String getId(); //获取sessionId


    <T> T getAttribute(String attributeName); //获取对用属性的Value


    Set<String> getAttributeNames(); //获取属性名字


    void setAttribute(String attributeName, Object attributeValue); //设置属性


    void removeAttribute(String attributeName); //删除属性

}


SessionRepository 用来增删改查 Session 在对应数据源中的接口

public interface SessionRepository<Sextends Session> {


    S createSession(); //创建session


    void save(S session); //更新session


    S getSession(String id);//根据 ID 来获取 Session


    void delete(String id);//根据 ID 来删除 Session

}

Spring Session 认为将请求与特定的 session 实例关联起来的问题是与协议相关的,因为在请求 / 响应周期中,客户端和服务器之间需要协商同意一种传递 session id 的方式。例如,如果请求是通过 HTTP 传递进来的,那么 session 可以通过 HTTP cookie 或 HTTP Header 信息与请求进行关联。如果使用 HTTPS 的话,那么可以借助 SSL session id 实现请求与 session 的关联。如果使用 JMS 的话,那么 JMS 的 Header 信息能够用来存储请求和响应之间的 session id。

对于 HTTP 协议来说,Spring Session 定义了HttpSessionStrategy接口以及两个默认实现,即CookieHttpSessionStrategy和HeaderHttpSessionStrategy,其中前者使用 HTTP cookie 将请求与 session id 关联,而后者使用 HTTP header 将请求与 session 关联

Spring Session 对 HTTP 的支持

Spring Session 对 HTTP 的支持是通过标准的 servlet filter(SessionRepositoryFilter) 来实现的,这个 filter 必须要配置为拦截所有的 web 应用请求,并且它应该是 filter 链中的第一个 filter。Spring Session filter 会确保随后调用javax.servlet.http.HttpServletRequest的getSession()方法时,都会返回 Spring Session 的HttpSession实例,而不是应用服务器默认的 HttpSession

每个浏览器多个 Session

Spring Session 会为每个用户保留多个 session,这是通过使用名为“_s”的 session 别名参数实现的。例如,如果到达的请求为 http://example.com/doSomething?_s=0 ,那么 Spring Session 将会读取“_s”参数的值,并通过它确定这个请求所使用的是默认 session。

如果到达的请求是 http://example.com/doSomething?_s=1的话,那么 Spring Session 就能知道这个请求所要使用的 session 别名为 1. 如果请求没有指定“_s”参数的话,例如 http://example.com/doSomething,那么 Spring Session 将其视为使用默认的 session,也就是说_s=0。

要为某个浏览器创建新的 session,只需要调用javax.servlet.http.HttpServletRequest.getSession()就可以了,就像我们通常所做的那样,Spring Session 将会返回正确的 session 或者按照标准 Servlet 规范的语义创建一个新的 session。下面的表格描述了针对同一个浏览器窗口,getSession()面对不同 url 时的行为



如上面的表格所示,session 别名不一定必须是整型,它只需要区别于其他分配给用户的 session 别名就可以了。但是,整型的 session 别名可能是最易于使用的,Spring Session 提供了HttpSessionManager接口,这个接口包含了一些使用 session 别名的工具方法。

我们可以在HttpServletRequest中,通过名为“org.springframework.session.web.http.HttpSessionManager”的属性获取当前的HttpSessionManager。如下的样例代码阐述了如何得到 HttpSessionManager,并且在样例注释中描述了其关键方法的行为


以上大致介绍了下spring-session的整体架构以及核心接口和过滤器,下边我介绍下如果实现单浏览器多session

首先在启动类中加入@EnableSpringHttpSession 注解告诉应用我采用spring-session来管理容器的session

配置一个cookieConfig


注入spring-session依赖的存储容器,我这里用的是内存存储Map结构模型存储,还可以用redis,mongodb等(目前最常用的是redis)


最后自定义一个过滤器让他处于过滤器的最顶端保证此过滤器在SessionRepositoryFilter前执行原因是因为在这个自定义过滤器中要通过一定的业务规则告诉spring-session要选用哪个session比如说session容器中现在用_s0,_s1 要通过具体的业务规则选用session的索引我这里是通过我们业务上的租户来选用具体可以参考如下:


选用完具体的session以后,把请求过来的url加入_s参数,此参数就表示要告诉SessionRepositoryFilter 来选用哪个session如果有就用,没有就新创建session

至此一个相对完整单浏览器多session方案就形成了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容

  • 原文链接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao阅读 4,692评论 0 9
  • IOC 控制反转容器控制程序对象之间的关系,而不是传统实现中,有程序代码之间控制,又名依赖注入。All 类的创建,...
    irckwk1阅读 940评论 0 0
  • 一. Java基础部分.................................................
    wy_sure阅读 3,810评论 0 11
  • 思维导图: 一、为什么需要session共享 HttpSession是由servelet容器进行管理的。而我们常用...
    barry_di阅读 12,226评论 7 39
  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 812评论 0 0