在Web项目开发中,会话管理是一个很重要的部分,用于存储与用户相关的数据。通常是由符合session规范的容器来负责存储管理,也就是一旦容器关闭,重启会导致会话失效。因此打造一个高可用性的系统,必须将session管理从容器中独立出来。而这实现方案有很多种,下面简单介绍下:

  第一种是使用容器扩展来实现,大家比较容易接受的是通过容器插件来实现,比如基于Tomcat的tomcat-redis-session-manager,基于Jetty的jetty-session-redis等等。好处是对项目来说是透明的,无需改动代码。不过前者目前还不支持Tomcat 8,或者说不太完善。个人觉得由于过于依赖容器,一旦容器升级或者更换意味着又得从新来过。并且代码不在项目中,对开发者来说维护也是个问题。

  第二种是自己写一套会话管理的工具类,包括Session管理和Cookie管理,在需要使用会话的时候都从自己的工具类中获取,而工具类后端存储可以放到Redis中。很显然这个方案灵活性最大,但开发需要一些额外的时间。并且系统中存在两套Session方案,很容易弄错而导致取不到数据。

  第三种是使用框架的会话管理工具,也就是本文要说的spring-session,可以理解是替换了Servlet那一套会话管理,既不依赖容器,又不需要改动代码,并且是用了spring-data-redis那一套连接池,可以说是最完美的解决方案。当然,前提是项目要使用Spring Framework才行。

  这里简单记录下整合的过程:

  如果项目之前没有整合过spring-data-redis的话,这一步需要先做,在maven中添加这两个依赖:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session</artifactId>
    <version>1.0.2.RELEASE</version>
</dependency>

  再在applicationContext.xml中添加以下bean,用于定义redis的连接池和初始化redis模版操作类,自行替换其中的相关变量。

<!-- redis -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
</bean>
 
<bean id="jedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="${redis.host}" />
    <property name="port" value="${redis.port}" />
    <property name="password" value="${redis.pass}" />
    <property name="timeout" value="${redis.timeout}" />
    <property name="poolConfig" ref="jedisPoolConfig" />
    <property name="usePool" value="true" />
</bean>
 
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
 
<!-- 将session放入redis -->
<bean id="redisHttpSessionConfiguration"
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>

  这里前面几个bean都是操作redis时候使用的,最后一个bean才是spring-session需要用到的,其中的id可以不写或者保持不变,这也是一个约定优先配置的体现。这个bean中又会自动产生多个bean,用于相关操作,极大的简化了我们的配置项。其中有个比较重要的是springSessionRepositoryFilter,它将在下面的代理filter中被调用到。maxInactiveIntervalInSeconds表示超时时间,默认是1800秒。写上述配置的时候我个人习惯采用xml来定义,官方文档中有采用注解来声明一个配置类。

  然后是在web.xml中添加一个session代理filter,通过这个filter来包装Servlet的getSession()。需要注意的是这个filter需要放在所有filter链最前面。

<!-- delegatingFilterProxy -->
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  这样便配置完毕了,需要注意的是,spring-session要求Redis Server版本不低于2.8。

  验证:使用redis-cli就可以查看到session key了,且浏览器Cookie中的jsessionid已经替换为session。

127.0.0.1:6379> KEYS *
1) "spring:session:expirations:1440922740000"
2) "spring:session:sessions:35b48cb4-62f8-440c-afac-9c7e3cfe98d3"

本文链接地址:http://dorole.com/1422/

使用Spring Session做分布式会话管理的更多相关文章

  1. Spring Session实现分布式session的简单示例

    前面有用 tomcat-redis-session-manager来实现分布式session管理,但是它有一定的局限性,主要是跟tomcat绑定太紧了,这里改成用Spring Session来管理分布 ...

  2. [ASP.NET][Session] 使用 SQLServer 会话管理解决 Session 丢失问题

    使用 SQLServer 会话管理解决 Session 丢失问题 步骤 1.通过命令行执行 aspnet_regsql.exe 程序(不要双击安装),先在 CMD 中输入命令 cd C:\Window ...

  3. Spring Session解决分布式Session问题的实现原理

    使用Spring Session和Redis解决分布式Session跨域共享问题 上一篇介绍了如何使用spring Session和Redis解决分布式Session跨域共享问题,介绍了一个简单的案例 ...

  4. Spring Security实现RBAC权限管理

    Spring Security实现RBAC权限管理 一.简介 在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的 Shiro和Spring Security.由于Spr ...

  5. 使用Spring Session实现Spring Boot水平扩展

    小编说:本文使用Spring Session实现了Spring Boot水平扩展,每个Spring Boot应用与其他水平扩展的Spring Boot一样,都能处理用户请求.如果宕机,Nginx会将请 ...

  6. Re:从零开始的Spring Session(一)

    Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...

  7. 实战开发,使用 Spring Session 与 Spring security 完成网站登录改造!!

    上次小黑在文章中介绍了四种分布式一致性 Session 的实现方式,在这四种中最常用的就是后端集中存储方案,这样即使 web 应用重启或者扩容,Session 都没有丢失的风险. 今天我们就使用这种方 ...

  8. Spring Session解决Session共享

    1. 分布式Session共享   在分布式集群部署环境下,使用Session存储用户信息,往往出现Session不能共享问题.   例如:服务集群部署后,分为服务A和服务B,当用户登录时负载到服务A ...

  9. OWASP 关于会话管理 - 译文 [原创]

    英文原文:https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Session_Management_Cheat_Shee ...

随机推荐

  1. C#&java重学笔记(变量与操作符)

    声明:自用参看读物 C#部分 1.C#中的byte和sbyte并不是二进制的比特,而是无符号 和 有符号的 8位整数. 2.decimal和float double都用来表示小数,前者用e的10的几次 ...

  2. iOS数组和字符串的转化

    NSMutableArray *components = [messageStr componentsSeparatedByString:@"*"] ; 反过来为 NSStrig ...

  3. Xamarin for Visual Studio 3.11.666 稳定版 破解补丁 Version 3

    前提概要 1.全新安装请参考 安装 Xamarin for Visual Studio. 2.本次补丁包含: ① Xamarin for Visual Studio 3.11.666 ② Xamari ...

  4. facebook design question 总结

    http://blog.csdn.net/sigh1988/article/details/9790337 这里原帖地址: http://www.mitbbs.com/article_t/JobHun ...

  5. java控制反转与依赖注入

    1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...

  6. 读取excel文件内容代码

    最近工作需要批量添加映射excel文件字段的代码  于是通过读取excel2007实现了批量生成代码,记录下代码 需要引入poi的jar包 import java.awt.List; import j ...

  7. SVN的使用(转载)

    MyEclipse中的SVN操作手册   导入项目 点击工具栏中的File-Import,进入下图: 点击Nex进入下图: 点击Next进入下图,输入你SVN服务器的IP地址,包括端口号和文件夹等完整 ...

  8. Android核心分析之二十五Android GDI之共享缓冲区机制

    Androird GDI之共享缓冲区机制 1  native_handle_t对private_handle_t 的包裹     private_handle_t是gralloc.so使用的本地缓冲区 ...

  9. WebBrowser控件应用:弹出新窗体和关闭窗口

    缘起:上次写了一个<WebBrowser控件的简单应用2>,提到了在NewWindow事件中打开新窗口的例子.有网友“队长 ”提出那个事件得到的参数是本页面的,而不是新页面的,经过测试,果 ...

  10. spry菜单栏(二)

    自定义选项卡式面板构件 尽管使用属性检查器可以简化对选项卡式面板构件的编辑,但是属性检查器并不支持自定义的样式设置任务.您可以修改选项卡式面板构件的 CSS 规则,并创建根据自己的喜好设置样式的构件. ...