Spring Session 是 Spring 的项目之一。Spring Session 提供了一套创建和管理 Servlet HttpSession 的方案,默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的 问题。
搭建案例环境
项目简单介绍,创建了一个父项目,两个聚合模块的子项目 父项目为pom项目 子项目为jar项目
1.创建父项目
创建项目 ,修改pom文件
注 :需要继承SpringBoot父项目的启动器,添加项目运行环境,相关的jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- SpringBoot父项目的启动器 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ah.szxy.springsession</groupId>
<artifactId>01-SpringSession</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Spring session data redis-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<!--<version>2.1.4.RELEASE</version>-->
</dependency>
<!--Lettuce是 一 个 基 于 Netty的 NIO方 式 处 理 Redis的 技 术 -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.创建两个子项目
session_service1,session_service2
pom文件(二者除名称外相同)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ah.szxy.springsession</groupId>
<artifactId>01-SpringSession</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>session_service1</artifactId>
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
</project>
注意 :在添加properties内的代码后,即可解决pom文件第一行报异常的问题
全局配置文件(除应用名, 端口号外相同)
spring:
application:
name: Spring-Session-Servlet1
redis:
#redis单机配置
host: 192.168.179.131
port: 6379
# 选择redis的数据库的分库
database: 5
#redis连接池配置
jedis:
pool:
max-idle: 10
min-idle: 5
max-active: 100
max-wait: 3000
timeout: 6005
server:
port: 8081
启动类(相同)
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/** * @EnableRedisHttpSession开启redis对SpringSession的支持 * @author chy * */
@SpringBootApplication
@EnableRedisHttpSession
public class SpringSessionApp {
public static void main(String[] args) {
SpringApplication.run(SpringSessionApp.class, args);
}
}
session_service1 :Controller
@RestController
@RequestMapping("service1")
public class WebController {
@RequestMapping("setMsg")
public String getMsg(HttpSession session) {
session.setAttribute("msg", "Hello SpringSession!");
return "ok";
}
}
session_service2 :Controller
@RestController
@RequestMapping("service2")
public class WebController {
@RequestMapping("getMsg")
public String getMsg(HttpSession session) {
String msg=(String) session.getAttribute("msg");
return msg;
}
}
3.测试结果 访问session_service1的controller查看结果
查看redis数据库是否存放了session数据
默认的保存的时间约为2100s
访问session_service2 的controller查看结果
在上面的案例中进行修改
1.两个子模块都添加实体类
因为涉及对象类型数据传输到redis,故需要实现序列化接口
package ah.szxy.domain;
import java.io.Serializable;
public class Users implements Serializable{
private String username;
private String userpwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
@Override
public String toString() {
return "Users [username=" + username + ", userpwd=" + userpwd + "]";
}
public Users() {
super();
}
public Users(String username, String userpwd) {
super();
this.username = username;
this.userpwd = userpwd;
}
}
2.子模块1的controller
@RequestMapping("addUser")
public String addUser(HttpSession session,Users user) {
session.setAttribute("user", user);
return "addUser Success!!!";
}
3.测试结果
访问session_service1的controller查看结果 查看redis数据库是否存放了session数据 访问session_service2 的controller查看结果
spring:session:expirations:(Set 结构)
用户 ttl 过期时间记录 , 这个 key中的值是一个时间戳, 根据这个 Session 过期时刻滚动至下一分钟而计算得出。 这个 key 的过期时间为 Session 的最大过期时间 +5 分钟(再此为2100s)。
spring:session:sessions:(Hash 结构) maxInactiveInterval:过期时间间隔 creationTime:创建时间 lastAccessedTime:最后访问时间 sessionAttr:Attributes 中的数据存储 Session 的详细信息,包括 Session 的过期时间间隔、最后的访问时间、attributes 的值。这个 key 的过期时间为 Session 的最大过期时间 +5 分钟。
spring:session:sessions:expires:(String 结构)
过期时间记录 : 这个 k-v 不存储任何有用数据,只是表示 Session 过期而设置。 这个 key 在 Redis 中的过期时间即为 Session 的过期时间间隔
修改启动类的@EnableRedisHttpSession注解
@SpringBootApplication
/** * 设置超时时限 * 需要两端同步,单位秒 */
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=20)
@SpringBootApplication
public class SessionServlet1Application {
public static void main(String[] args) {
SpringApplication.run(SessionServlet1Application.class, args);
}
}
点击注解即可进入相应的注解接口 ,可以看到其中有四个属性
属性 | 作用 |
---|---|
maxInactiveIntervalInSeconds | 设置 Session 的失效时间,单位为秒。默认(1800 秒)30 分钟。 |
redisNamespace | 为键定义唯一的命名空间。该值用于通过更改前缀与默认 spring:session 隔离会话 |
redisFlushMode | Redis 会话的刷新模式。默认值为“保存” |
cleanupCron | 过期会话清理作业的 cron 表达式。默认值(“0 *****”)每分钟运行一次。 |
SpringSession 中默认的序列化器为 jdk 序列化器,该序列化器效率低下,内存再用大。 我们可以根据自己的需要更换其他序列化器,如 GenericJackson2JsonRedisSerializer 序列化器。 使用配置类跟换序列器
/** * 1.需要两端都添加这个配置类 * 2.同时允许关联对象的添加 * @author 曹海洋 * */
@Configuration
public class SpringSessionConfig {
/** * 更换序列化器 * @return */
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer setSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
注意 : 1.如果在项目中使用序列化其,建议使用这里推荐的序列化器序列化器的配置类 2.将原来的数据清空 3.不要额外导入jar, 上面添加的坐标包含的jar足够
配置前
配置后
1 什么是Spring Session MongoDB Spring Session MongoDB 是Spring Session 的二级项目。其功能与Spring Session 是相同的。 Spring Session MongoDB 提供了一个API 和实现,用于通过利用Spring Data MongoDB来管理存储在MongoDB 中的用户会话信息。
2 与Spring Session 的区别 Spring Session 与Spring Session MongoDB 的作用是相同的。都是来解决Session 共享问题。 不同的是Spring Session 默认的是依赖于Redis 作为数据缓存平台,而Spring SessionMongoDB 是依赖于MongoDB 来作为数据缓存平台的。
下载 MongoDB
本次使用版本: mongodb-linux-x86_64-4.0.9.tgz
解压 tgz 文件并复制到/usr/local目录下
tar-zxfmongodb-linux-x86_64-4.0.9.tgz
cp mongodb-linux-x86_64-4.0.9 /usr/local/mongodb -rf
进入mongodb目录下, 创建数据库目录
mkdir -p data/db
创建一个文件夹etc, 统一存放日志文件和配置文件
mkdir etc
创建日志文件
touch mongodb.log
创建配置文件
vim mongodb.conf
配置文件中的内容
dbpath=/usr/local/mongodb/data/db
logpath=/usr/local/mongodb/etc/mongodb.log
port=27017
fork=true
bind_ip=0.0.0.0
启动 MongoDB
./mongod --config /usr/local/mongodb/etc/mongodb.conf
创建自定义库(chy)
#登录客户端
./mongo
#库存在就切换到该库,不存在就创建
use chy
常用操作指令
#1. 启动
./mongod --config 配置文件位置
#列如:
./mongod --config /usr/local/mongodb/etc/mongodb.conf
#2. 关闭
./mongod --shutdown --config 配置文件位置
#例如:
./mongod --shutdown --config /usr/local/mongodb/etc/mongodb.conf
环境搭建
创建一个父项目,两个子项目 父项目为pom项目,规定所用jar版本与种类 子项目为jar项目,实现具体的模拟内容
1.创建父项目,修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>ah.szxy.springSession</groupId>
<artifactId>02-SpringSession-MongoDB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<!--Spring session data mondodb -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<modules>
<module>session_mongo2</module>
</modules>
</project>
2.创建两个子项目,无需修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ah.szxy.springSession</groupId>
<artifactId>02-SpringSession-MongoDB</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>session_mongo1</artifactId>
</project>
注意:两个pom文件除名称不一样外,其他一致
3.修改全局配置文件 application.yml
server:
port: 8081
spring:
application:
name: Session-Mongdb1
session:
store-type: mongodb
data: #配置MongoDB的连接参数
mongodb:
host: 192.168.179.131
port: 27017
database: chy #自定义MongoDB库名称
注意:两个配置文件处理应用名,端口号不一样外,其他一致
4.启动类
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
@SpringBootApplication
@EnableMongoHttpSession
public class SessionMongoApp {
public static void main(String[] args) {
SpringApplication.run(SessionMongoApp.class, args);
}
}
注:两个启动类完全一致
4.session_mongo1的controller
@RestController
@RequestMapping("service1")
public class MongoDBController {
@RequestMapping("setMsg")
public String showMsg(HttpSession session) {
session.setAttribute("msg", "Hello MongoDB!!!");
return "ok";
}
}
5.session_mongo2的controller
@RestController
@RequestMapping("service2")
public class MongoDBController {
@RequestMapping("getMsg")
public String showMsg(HttpSession session) {
String msg = (String) session.getAttribute("msg");
return msg;
}
}
6.测试结果
启动两个项目, 访问session_mongo1的controller
访问session_mongo2的controller
1.两个子模块都要创建Users实体类
package ah.szxy.domain;
import java.io.Serializable;
public class Users implements Serializable{
private String username;
private String userpwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
@Override
public String toString() {
return "Users [username=" + username + ", userpwd=" + userpwd + "]";
}
public Users() {
super();
}
public Users(String username, String userpwd) {
super();
this.username = username;
this.userpwd = userpwd;
}
}
注意:勿忘实现序列化接口
2.session_mongo1的controller中添加方法
@RequestMapping("addUser")
public String showMsg(HttpSession session,Users user) {
session.setAttribute("user", user);
return "ok";
}
3.session_mongo2的controller中添加方法
@RequestMapping("getUser")
public Users showUser(HttpSession session) {
Users user=(Users) session.getAttribute("user");
return user;
}
4.测试结果
使用其专用的查询语句即可查看它的存储结构
整理如下 点击使用json格式校验/转换
{
"_id": "138af2fe-cf3f-4e8d-8ea1-a311ecd70edc",
"created": ISODate("2019-09-16T08:42:51.767Z"),
"accessed": ISODate("2019-09-16T09:07:10.425Z"),
"interval": "PT30M",
"principal": null,
"expireAt": ISODate("2019-09-16T09:37:10.425Z"),
"attr": BinData(0, "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAACdAADbXNndAAQSGVsbG8gTW9uZ29EQiEhIXQABHVzZXJzcgAUYWguc3p4eS5kb21haW4uVXNlcnOYj4Y/edg3CAIAAkwACHVzZXJuYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7TAAHdXNlcnB3ZHEAfgAGeHB0AANjaHl0AAl0aW1lcGF1c2V4")
}
/** * @EnableMongoHttpSession * maxInactiveIntervalInSeconds: 设置超时时限, 两个子模块的这个属性必须一致 * collectionName: 可省略,唯一标识,使用时两个子模块的这个属性必须一致 */
@SpringBootApplication
@EnableMongoHttpSession(maxInactiveIntervalInSeconds=20,collectionName="test")
public class SessionMongoApp {
public static void main(String[] args) {
SpringApplication.run(SessionMongoApp.class, args);
}
}
注意 : @EnableMongoHttpSession注解的两个属性的用法
属性 | 作用 |
---|---|
maxInactiveIntervalInSeconds | 设置 Session 失效时间 ,默认为2100s |
collectionName | 设置 MongoDB 的 Collections 的名称 ,默认为seesions |
默认使用的是jdk序列化器,序列化后产生的数据较大,占用内存较高,因此最好换成其他的序列化器
@Configuration
public class SerializableConfig {
@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
return new JacksonMongoSessionConverter();
}
}
启动项目时报错,因为json转换时对对象的属性做了校验, 而自定义对象的属性不在白名单中,我们需要关闭属性的自动校验。
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
public class User implements Serializable {
private String username;
private String userpwd;
...
}
mongodb中存储的数据
{
"_id" : "36d3dd35-e33d-49f8-bde9-ec3587e2d560",
"@class" : "org.springframework.session.data.mongo.MongoSession",
"createdMillis" : NumberLong(1566549133774),
"accessedMillis" : NumberLong(1566549137807),
"intervalSeconds" : 20,
"expireAt" : ISODate("2019-08-23T08:32:37.807Z"),
"attrs" : {
"@class" : "java.util.HashMap",
"user" : {
"@class" : "cn.xyl.pojo.User",
"_id" : 123,
"name" : "hello"
}
},
"principal" : null
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/181298.html原文链接:https://javaforall.cn