Springboot整合springsession实现session共享 您所在的位置:网站首页 tomcat实现session共享 Springboot整合springsession实现session共享

Springboot整合springsession实现session共享

2024-06-02 10:05| 来源: 网络整理| 查看: 265

Springboot整合springsession实现session共享 简介

session我们之前有介绍过(可见springboot整合springsecurity),简单来说就是将用户信息或者数据存储在服务器上,通常用于验证用户身份或者避免通过获取相关信息。

但是,缺点也是非常明显:

占用服务器负载:我们可以使用token,用时间换取空间

对于多服务器环境,session无法共享

对于第二点缺点,我们目前有几种比较常用的解决方法

使用cookie加密的方式将session保存在客户端上

优点是可以减轻服务器压力,缺点是每次请求都要带上cookie信息,占用一定带宽。此外若用户禁用cookie则无法使用

服务器间同步

通过配置tomcat集群,在集群中广播自己的session信息,但是缺点很明显,当集群规模较大时,会占用大量资源来进行session同步处理

基于分布式缓存的session共享机制

将session缓存到redis中,这样不同服务器都可以直接到内存中获取session,效率高,也最常用

Springsession

springSession是 spring 旗下的一个项目,把 servlet 容器实现的 httpSession替换为springSession,专注于解决session管理问题。可简单快速且无缝的集成到我们的应用中。

springsession就是spring的一个框架,实现了我们上面说的基于分布式缓存的session共享机制

操作实例

我们先来看看简单的操作实例

程序源码

pom.xml org.springframework.session spring-session-data-redis 2.5.0 org.springframework.boot spring-boot-starter-data-redis 2.5.1 application.yml spring: redis: # 数据库索引,默认为0 database: 0 # redis host ip host: 192.168.56.129 # redis 连接端口 port: 6379 # 服务器连接密码(默认为空) password: # 连接超时时间(毫秒) timeout: 1000 #设置springsession存储类型,默认为redis session: store-type: redis 启动类加上@EnableRedisHttpSession @SpringBootApplication @EnableRedisHttpSession public class SpringsessionApplication { public static void main(String[] args) { SpringApplication.run(SpringsessionApplication.class, args); } } SessionController

这里我们构建一个简单的controller测试是否实现了session共享

@RestController @RequestMapping("/session") public class SessionController { /** * 设置session * @param request * @param attributes * @return */ @PostMapping("/set") public Map setSession(HttpServletRequest request, @RequestParam("attributes")String attributes){ request.getSession().setAttribute("attributes",attributes); Map map = new HashMap(); map.put("SessionID:",request.getSession().getId()); return map; } /** * 获取session * @param request * @return */ @GetMapping("/get") public String getSession(HttpServletRequest request){ String attributes = (String) request.getSession().getAttribute("attributes"); return attributes; } }

两个方法都很简单

setSession:通过请求中的参数设置session中的attributes

getSession:测试是否能获取在其他端口设定的session中对应attributes的值

运行结果

由于要体现session共享,所以我们这里将在两个不同端口运行程序

通过IDEA不同端口启用同一个项目,可以在右上角运行处选择edit config,然后添加springboot项目,并同意parallel run

port:8080 /session/set

可以看到成功设置了session并且返回了SessionID

port:8090 /session/get

成功获取到了session中的值,标明我们实现了session共享

我们再来看看redis存储的session

这里以sessionID为KEY,session为value存储,但是sessionID前面的命名空间太长了,而且不具有项目标识,我们可以通过在application.yml中设置namespace="xx"即可

Springsession 逻辑分析

我们可以看到springsession使用非常简单,对于用户几乎不用进行什么操作,那么springsession具体为我们做了什么工作呢?

其实springsession通过autoconfigure帮我们自动配置了一个过滤器SessionRepositoryFitlter

SessionRepositoryFitlter @Order(-2147483598) public class SessionRepositoryFilter extends OncePerRequestFilter {

定义来看:

这里为SessionRepositoryFilter设定了一个非常小的order值,以确保能够在filterchain中被优先执行。

优先执行是为了将原生HttpRequest进行替换和封装

继承了OncePerRequestFilter,确保一次请求只通过一次

源码命名太长,直接贴代码太乱了,这里就直接截图了

可以看到,我们这里首先对request和response进行封装,之后将封装请求传入doFilter()

所以具体逻辑就在两个封装类中,这里我们着重关注request的封装类

获取session的逻辑如下:

this.getCurrentSession() 检查serlvet容器中是否有session,如果有session则直接返回,如果没有则去redis中去拿

this.getRequestedSession() 根据请求中的信息获取sessionID,然后根据sessionID去redis中获取session

这里并不是每次查询都是去redis中查询,而是设置了一个session缓存,每次查询先检查缓存中有没有,如果有则直接拿值,如果没有则通过httpSessionIdResolver.resolveSessionIds(this)获取sessionID

获取sessionid有两种方式,一种是根据请求中Header信息获取,一种是放在cookie中

我们这里httpSessionIdResolver = new CookieHttpSessionIdResolver()选择使用cookie获取sessionID

查询到session之后,更新session相关信息并返回

如果在redis中没有找到,则根据create判断是否创建新的session

基本的逻辑非常清楚也非常好理解,我们再来具体看看springsession是如何在redis中查询session的

SessionRepository

springsession为我们提供了这样一个session仓库,能够完成对session的CRUD操作

我们这里使用的是RedisSessionRepository,实现了将session存储在redis上的CRUD操作

这就是我们getRequestedSession()中使用的findById()

可以看到里面就是对redis数据库的直接操作

总结

本文主要介绍了springboot如何整合springsession实现session共享,也简单介绍了其中逻辑原理,具体的部分还是建议仔细阅读源码。

redis上的CRUD操作

[外链图片转存中…(img-guh79ZOd-1624583023491)]

这就是我们getRequestedSession()中使用的findById()

可以看到里面就是对redis数据库的直接操作

总结

本文主要介绍了springboot如何整合springsession实现session共享,也简单介绍了其中逻辑原理,具体的部分还是建议仔细阅读源码。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有