普通注册 - 普通登录
开源之家-免费素材_软件_模板_源码下载-更快的站长下载站

开源之家-免费素材_软件_模板_源码下载-更快的站长下载站

多个SpringBoot项目采用redis实现Session共享功能

时间:2020-09-08 12:43 [[其它教程]] 作者:开源之家 浏览:

有时我们可能有多个不同的Web应用,可以相互调用,这时如果每个应用都有自己的session,那用户跳转到另一个应用时就又需要登陆一次,这样会带来很不好的体验,因此我们需要在不同的应用中共享session。这里,我们采用redis来实现。

前置说明

由于只用到redis和springboot的整合,所以只能实现一个URL下的不同端口的应用之间的session共享,如果连应用名称都完全不同的两个应用要实现session共享,在这个基础上还需要使用到Nginx,这种方式我暂时还没有试过。(SpringBoot项目默认就是不带应用名称的,除非自己在配置文件中修改过)

需要提前在本地安装好redis,或者连接远程redis服务器。这里就不写安装教程了,可以自行去网上搜索。

添加依赖

需要为springboot项目添加以下两个依赖,参与session共享的项目都需要添加。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
 
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

一个是redis的依赖,一个是spring-session-data-redis的依赖。

配置redis参数

在SpringBoot项目的application.properties配置文件中配置redis参数:

# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址,如果是远程redis服务器,就改成服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口,默认是6379
spring.redis.port=6379
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
spring.session.store-type=redis

如果你的项目使用的是application.yml,就进行如下配置:

spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1ms
timeout: 5000
session:
store-type: redis

配置session过期时间

创建一个用于配置session过期时间的配置类:

import org.springframework.context.annotation.Configuration;
importorg.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
 
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class SessionConfig {
}

简单的登录逻辑

@RequestMapping("/doLogin")
public String doLogin(HttpServletRequest request, Model model){
String username = request.getParameter("username");
String password = request.getParameter("password");
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
model.addAttribute("errorMsg", "用户名和密码不能为空");
return "login";
}
// 查找该用户,成功后根据该用户的类别返回到对应页面
User user = userService.getUserByUsernameAndPassword(username, password);
if(user == null) {
model.addAttribute("errorMsg", "用户名或密码错误");
return "login";
} else {
request.getSession().setAttribute("currentUser", user);
model.addAttribute("currentUser", user);
String identity = user.getIdentity();
if("admin".equals(identity)){
return "admin";
}else{
return "user";
}
}
}

直接按照原来的方式将对象存入session:request.getSession().setAttribute("currentUser", user); 此时session会存入redis。

登录过滤器

@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Objecthandler)
throws Exception {
HttpSession session = request.getSession();
User currentUser = (User) session.getAttribute("currentUser");
if(currentUser == null){
response.sendRedirect(request.getContextPath() + "/toLogin");
return false;
}else{
return true;
}
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponsehttpServletResponse,
Object o, ModelAndView modelAndView) throws Exception {
 
}
 
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponsehttpServletResponse,
Object o, Exception e) throws Exception {
 
}
}

同样按原来的方式从session中取出对象:User currentUser = (User) session.getAttribute("currentUser"); 此时会从redis中取出该对象。

注意

如果只是存字符串等redis可以直接解析的对象,那就不会有什么问题,但是如果是存取对象就需要进行序列化了,比如上文中存的是我自定义的一个User对象,那么在存的时候,是会对该对象进行序列化的,取出时也会进行反序列化,因此该对象要实现Serializable接口,并且需要进行session共享的项目中都要有一个一模一样的对象,比如我的User定义如下:

import java.io.Serializable;
 
public class User implements Serializable {
 
private String id;
private String username;
private String password;
private String email;
private String identity;
private static final long serialVersionUID = -5809782578272943999L;
// 省略getter、setter方法
}

注意这个序列号serialVersionUID,不同应用中的User对象的这个序列号必须相同,否则无法正确进行反序列化。

转载请注明来源: 多个SpringBoot项目采用redis实现Session共享功能

本文永久链接地址: https://www.enboo.cn/CMSjiaocheng/qitajiaocheng/21472.html

文本标签:SpringBoot项目

郑重声明:
本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。
若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。 我们不承担任何技术及版权问题,且不对任何资源负法律责任。
如无法链接失效或侵犯版权,请给我们来信:2225329841@qq.com