SpringBoot 集成 Spring Session
SpringBoot 集成 Spring Session
应该讲解清楚,为什么要使用 Redis 进行 Session 的管理。
Session 复制又是什么概念。
Spring Session 在汪云飞老师的书里的介绍是:
Spring Session:提供一个 API 及实现来管理用户会话信息。
我们可以这样理解,原来在 Tomcat 服务器中存在的 Session 统一放置在 Redis 中进行管理。
这样在服务器集群的时候,就不会出现状态不一致的情况。(这一步还须要描述详细一些,最好把自己实验的过程展示一下)。
第 1 步:添加依赖
除了 SpringBoot 最最基础的依赖 spring-boot-starter-web
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.2.RELEASE'
以外,我们还须要添加 spring-boot-starter-data-redis 和 spring-session
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '1.5.2.RELEASE'
compile group: 'org.springframework.session', name: 'spring-session', version: '1.3.0.RELEASE'
另外,我们还须要 Redis 服务的支持。
第 2 步:添加 Spring Session 相关的配置
- 配置 Spring Session 使用 Redis 来进行统一管理,以及 Redis 的主机和端口号
spring.session.store-type=redis
spring.redis.host=localhost
spring.redis.port=6388
- 配置 Session 失效的时间
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 24 * 60 * 60)
public class SessionConfig {
}
下面编写测试代码。
@RestController
public class SessionController {
// 用于测试 SpringBoot 容器是否启动
// http:localhost:8080/test
@RequestMapping("/test")
public String test(){
return "PING OK";
}
// http:localhost:8080/put?key=name&value=liwei
@RequestMapping("/put")
public String put(HttpSession session,
@RequestParam("key") String key,@RequestParam("value") String value){
session.setAttribute(key,value);
return "PUT OK";
}
// http:localhost:8080/get?key=name
@RequestMapping("/get")
public String get(HttpSession session,
@RequestParam("key") String key){
String value = (String) session.getAttribute(key);
if(value == null || "".equals(value)){
return "NO VALUE GET";
}
return value;
}
}
我们执行
gradle clean build
然后再执行
java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8081
java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8082
java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8083
启动 3 台服务器。
实验的思路是这样的:在 1 台服务器上的 Session 中放入 key 和 value,在另外两台服务器上都可以获得 key 对应的 value。
第 1 步:请求
http://localhost:8081/put?key=age&value=24
第 2 步:
http://localhost:8082/get?key=age
http://localhost:8083/get?key=age
此时,在两台服务器 8082 和 8083 上可以看到我们在服务器 8081 的 Session 中放入的数据。
第 3 步:登录 Redis 服务端,情况 Redis 的缓存,再次执行第 2 步的请求,发现不能获得 Session 的数据。
redis-cli -p 6388
flushdb
至此,就说明此时 3 台服务器上的 Session 都由 Redis 来管理了。
如果我们把关于 Spring Session 和 Redis 的配置都去掉的话,就会发现在 1 台服务器上的 Session 的设置和获取都只能在这台服务器上完成。
补充说明:在 Gradle 项目中要通过使用 spring-boot 这个插件,才能使打出来的 jar 包可以执行 java -jar 开始运行。
配置方法:
allprojects {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
}
}
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
}
repositories {
jcenter()
mavenLocal()
mavenCentral()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url "http://repo.spring.io/release" }
maven { url "http://repo.spring.io/milestone" }
maven { url "http://repo.spring.io/snapshot" }
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "com.github.adrianbk:gradle-jvmsrc-plugin:0.6.1"
}
}
此时,就可以使用 spring-boot 插件了。
apply plugin: 'spring-boot'
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:93) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:171) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:86) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:778) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:670) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:388) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.0.RELEASE.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:91) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
... 33 common frames omitted
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
... 35 common frames omitted
User 类要实现序列化接口。
http://localhost:8081/put/user
http://localhost:8082/put/user
http://localhost:8083/put/user
这篇文章涉及到的源代码可以在我的 GitHub 上下载:https://github.com/weimingge14/SpringBootSessionDemo
SpringBoot 集成 Spring Session的更多相关文章
- springboot集成Spring Session
10.1 分布式集群环境下的集成(同域名.同项目) 10.1.1 创建SpringBoot的web支持项目07-springboot-session 创建项目 10.1.2 ...
- SpringBoot集成Spring Security(7)——认证流程
文章目录 一.认证流程 二.多个请求共享认证信息 三.获取用户认证信息 在前面的六章中,介绍了 Spring Security 的基础使用,在继续深入向下的学习前,有必要理解清楚 Spring Sec ...
- SpringBoot集成Spring Security(6)——登录管理
文章目录 一.自定义认证成功.失败处理 1.1 CustomAuthenticationSuccessHandler 1.2 CustomAuthenticationFailureHandler 1. ...
- SpringBoot集成Spring Security(4)——自定义表单登录
通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢, ...
- Springboot集成Spring Batch
Spring官网 (https://spring.io/projects/spring-batch#overview)对Spring Batch的解释: 一个轻量级的.全面的批处理框架,用于开发对企 ...
- SpringBoot集成Spring Security入门体验
一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...
- SpringBoot集成Spring Security(5)——权限控制
在第一篇中,我们说过,用户<–>角色<–>权限三层中,暂时不考虑权限,在这一篇,是时候把它完成了. 为了方便演示,这里的权限只是对角色赋予权限,也就是说同一个角色的用户,权限是 ...
- SpringBoot集成Spring Security(2)——自动登录
在上一章:SpringBoot集成Spring Security(1)——入门程序中,我们实现了入门程序,本篇为该程序加上自动登录的功能. 文章目录 一.修改login.html二.两种实现方式 2. ...
- Spring boot集成spring session实现session共享
最近使用spring boot开发一个系统,nginx做负载均衡分发请求到多个tomcat,此时访问页面会把请求分发到不同的服务器,session是存在服务器端,如果首次访问被分发到A服务器,那么se ...
随机推荐
- 虚拟机上首次安装Ubuntu后 root密码设置
虚拟机下安装ubuntu后root密码设置 问题描述: 在虚拟机下安装了ubuntu中要输入用户名,一般情况下大家都会输入一个自己的网名或绰号之类的,密码也在这时设置过了. 但是当安装成功之后,使用命 ...
- 006 Notepad++ 运行 C/C++
目录 0. 前言 1. 准备 2. 开工 setp 1 step 2 step 3 step 4 step 5 step 6 3. 修改与删除 3.1修改名称.快捷键 3.2 删除 4. 运行 5. ...
- [转帖]SQL 里面的 case when 的用法
SQL之case when then else end用法介绍 https://www.2cto.com/database/201804/740772.html 要培训了 看到有case when 之 ...
- Oracle Replace函数的简单使用
REPLACE ( char, search_string [, replace_string]) 如果没有指定replace_string 变量的值,那么当发现search_string 变量的 ...
- 几个 BeanUtils 中的坑,千万别踩!
背景 最近项目中在和第三方进行联调一个接口,我们这边发送http请求给对方,然后接收对方的回应,代码都是老代码. 根据注释,对方的SDK中写好的Request类有一个无法序列化的bug,所以这边重新写 ...
- 携程的 Dubbo 之路,值得学习!
注:本篇文章整理自董艺荃在 Dubbo 社区开发者日上海站的演讲. 1.缘起 携程当初为什么要引入 Dubbo 呢?实际上从 2013 年底起,携程内主要使用的就是基于 HTTP 协议的 SOA 微服 ...
- Ubuntu终端路径和文件夹相互切换
一. 环境配置 1. 打开终端输入安装命令 sudo apt-get install nautilus-open-terminal 2. 重新加载文件管理器 nautilus -q 3. 重启电脑 s ...
- 给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回
给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回 //统计字符串中出现的字符的出现次数 public function strNum(){ ...
- IntelliJ IDEA中创建Web聚合项目(Maven多模块项目)(转载)
创建parent项目 1.打开IDEA,注意这里不要勾选模板,用模板创建过maven项目的小伙伴都知道模板创建项目非常慢,所以这里不要选模板,需要的文件夹我们后面自己来创建就可以了.所以这个页面直接点 ...
- POJ练习计划
题目链接:https://cn.vjudge.net/article/348 2019/7/24: [POJ-1423] [题解] [POJ-1503] 模板题