单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式。本文是通过Spring Boot框架集成Redis缓存来实现session共享的,分享给大家仅供参考和学习。

有些人可能是初级Java工程师甚至刚刚接触Java编程,因此先普及一下Session的概念:Session是服务器端的一个key-value的数据结构,开发者经常把Session与cookie配合使用,用于保持登录用户的回话。

当客户端在第一次访问服务端时,服务端会响应一个sessionId并且将它存入到本地cookie中,之后每次访问都会将cookie中的sessionId放入到请求头中去请求服务器。如果通过这个sessionid无法找到对应的值,那么服务器会创建一个新的sessionid并且响应给客户端。

本文在前一篇“Spring Boot从入门到精通(六)集成Redis实现缓存机制”文章中的项目源码基础上(关注“Java精选”微信公众号,切换至后台->聚合->开源项目,可以查看Spring Boot系列从入门到精通教程),使用Spring Boot框架集成Redis缓存来实现session共享。Maven项目pom.xml文件在Spring Boot项目中pom.xml文件中,增加配置信息如下:

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

配置Redis缓存类文件

在前一篇文章源码的基础上(文章末尾有Spring Boot从入门到精通系列文章地址),集成Redis实现缓存机制的源码的基础上增加@EnableRedisHttpSession即可,具体代码如下:

package com.yoodb.study.demo04.datasource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class RedisConfig extends CachingConfigurerSupport { @Bean("redisTemplate")
@ConfigurationProperties(prefix="spring.redis")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); //将key的序列化设置成StringRedisSerializer
StringRedisSerializer keySerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setHashKeySerializer(keySerializer); redisTemplate.afterPropertiesSet();
return redisTemplate;
} }

@EnableRedisHttpSession:开启Session共享功能。使用此注解之后Session调用会自动通过Redis存储和获取。另外,想要达到Session共享的目的,在其他的系统上只需要做同样的配置即可。
其中maxInactiveIntervalInSeconds参数是设置Session失效时间,使用Redis
Session之后,原Spring Boot的server.session.timeout属性不再生效。

Spring Session Redis的源码分析打开@EnableRedisHttpSession注解源码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.session.data.redis.config.annotation.web.http; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.session.FlushMode;
import org.springframework.session.SaveMode;
import org.springframework.session.data.redis.RedisFlushMode; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({RedisHttpSessionConfiguration.class})
@Configuration(
proxyBeanMethods = false
)
public @interface EnableRedisHttpSession { //Session默认过期时间,秒为单位,默认30分钟
int maxInactiveIntervalInSeconds() default 1800;
//配置key的namespace,默认的是spring:session,如果不同的应用共用一个redis,应该为应用配置不同的namespace,这样才能区分这个Session是来自哪个应用。
String redisNamespace() default "spring:session"; //配置刷新Redis中Session的方式,默认是ON_SAVE模式,只有当Response提交后才会将Session提交到Redis
//此模式也可以配置成IMMEDIATE模式,这样的话所有对Session的更改都会立即更新到Redis。
/** @deprecated */
@Deprecated
RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; FlushMode flushMode() default FlushMode.ON_SAVE;
//清理过期Session的定时任务默认0,到时间自动清理。
String cleanupCron() default "0 * * * * *"; SaveMode saveMode() default SaveMode.ON_SET_ATTRIBUTE;
}

Controller类文件

前一篇项目源码的基础上,在BootUserController类文件中增加两个方法,具体代码如下:

package com.yoodb.study.demo04;

import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.yoodb.study.demo04.bean.BootUser;
import com.yoodb.study.demo04.service.BootUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController
@RequestMapping("/myt")
public class BootUserController {
@Autowired
private BootUserService service; @RequestMapping("/getUsers")
public List<BootUser> getUsers() {
List<BootUser> list = service.getUsers();
return list;
} @GetMapping(value = "/first")
public Map<String, Object> firstResp (HttpServletRequest request){
Map<String, Object> map = new HashMap<>();
StringBuffer requestUrl = request.getRequestURL();
request.getSession().setAttribute("requestUrl",requestUrl );
map.put("requestUrl", requestUrl);
return map;
} @GetMapping(value = "/sessions")
public Object sessions (HttpServletRequest request){
Map<String, Object> map = new HashMap<>();
map.put("sessionId", request.getSession().getId());
map.put("message", request.getSession().getAttribute("requestUrl"));
return map;
} }

Spring Boot项目启动

1、访问8080端口项目启动成功之后测试访问,访问8080端口的first地址:http://localhost:8080/myt/first返回json结果:

{"requestUrl":"http://localhost:8080/myt/first"}

通过redis客户端工具连接redis服务,可以看到redis中已经存在springsession相关数据,此时也可以看到设置的sessions值。

接着,访问8080端口的sessions地址:http://localhost:8080/myt/sessions返回json结果:

{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

2、访问9090端口配置application.properties文件,请求9090端口的设置,配置信息如下:

#指定端口号
server.port=9090

项目启动成功之后测试访问,访问9090端口的sessions地址:http://localhost:9090/myt/sessions

{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

注:通过返回json结果可以发现8080与9090两个服务返回的数据相同,那么恭喜已经实现了session的共享。如果此时访问9090端口的first地址,会发现与8080端口的访问地址端口号不相同:http://localhost:9090/myt/first返回json结果:

{"requestUrl":"http://localhost:9090/myt/first"}

8080和9090端口两个服务的sessions访问地址,都会返回如下json结果:

{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

结论:两个服务的访问地址不相同,但获取的session数据相同,说明已经实现了session共享,与前面说到的登录用户只需要登录验证一次就可以访问所有相互信任的应用系统呼应了。本文“Spring Boot从入门到精通(七)集成Redis实现Session共享”文章的项目源码(springboot-study-demo04)地址:项目地址:https://github.com/yoodb/springboot

本文转自:https://blog.yoodb.com/yoodb/article/detail/1571

Spring Boot集成Redis缓存实现session的共享就是这么简单。虽说简单,但在实际项目开发中还是比较应用广泛的,尤其是在分布式应用方面,通过Redis session共享与nginx负载均衡配合,实现分布式应用。下面大家不妨试一试,有什么疑问欢迎下方留言,看到后小编立马回复!

单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式。本文是通过Spring Boot框架集成Redis缓存来实现session共享的,分享给大家仅供参考和学习。

有些人可能是初级Java工程师甚至刚刚接触Java编程,因此先普及一下Session的概念:Session是服务器端的一个key-value的数据结构,开发者经常把Session与cookie配合使用,用于保持登录用户的回话。

当客户端在第一次访问服务端时,服务端会响应一个sessionId并且将它存入到本地cookie中,之后每次访问都会将cookie中的sessionId放入到请求头中去请求服务器。如果通过这个sessionid无法找到对应的值,那么服务器会创建一个新的sessionid并且响应给客户端。

本文在前一篇“Spring Boot从入门到精通(六)集成Redis实现缓存机制”文章中的项目源码基础上(关注“Java精选”微信公众号,切换至后台->聚合->开源项目,可以查看Spring Boot系列从入门到精通教程),使用Spring Boot框架集成Redis缓存来实现session共享。

Maven项目pom.xml文件

在Spring Boot项目中pom.xml文件中,增加配置信息如下:

1
2
3
4
<dependency>  
        <groupId>org.springframework.session</groupId>  
        <artifactId>spring-session-data-redis</artifactId>  
</dependency>

配置Redis缓存类文件

在前一篇文章源码的基础上(文章末尾有Spring Boot从入门到精通系列文章地址),集成Redis实现缓存机制的源码的基础上增加@EnableRedisHttpSession即可,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.yoodb.study.demo04.datasource;
 
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
 
 
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class RedisConfig extends CachingConfigurerSupport {
 
    @Bean("redisTemplate")
    @ConfigurationProperties(prefix="spring.redis")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
 
        //将key的序列化设置成StringRedisSerializer
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
 
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
   
}

@EnableRedisHttpSession:开启Session共享功能。使用此注解之后Session调用会自动通过Redis存储和获取。另外,想要达到Session共享的目的,在其他的系统上只需要做同样的配置即可。
其中maxInactiveIntervalInSeconds参数是设置Session失效时间,使用Redis
Session之后,原Spring Boot的server.session.timeout属性不再生效。

Spring Session Redis的源码分析

打开@EnableRedisHttpSession注解源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
 
package org.springframework.session.data.redis.config.annotation.web.http;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.session.FlushMode;
import org.springframework.session.SaveMode;
import org.springframework.session.data.redis.RedisFlushMode;
 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({RedisHttpSessionConfiguration.class})
@Configuration(
    proxyBeanMethods = false
)
public @interface EnableRedisHttpSession {
 
//Session默认过期时间,秒为单位,默认30分钟
    int maxInactiveIntervalInSeconds() default 1800;
//配置key的namespace,默认的是spring:session,如果不同的应用共用一个redis,应该为应用配置不同的namespace,这样才能区分这个Session是来自哪个应用。
    String redisNamespace() default "spring:session";
 
//配置刷新Redis中Session的方式,默认是ON_SAVE模式,只有当Response提交后才会将Session提交到Redis
    //此模式也可以配置成IMMEDIATE模式,这样的话所有对Session的更改都会立即更新到Redis。
    /** @deprecated */
    @Deprecated
    RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE;
 
    FlushMode flushMode() default FlushMode.ON_SAVE;
//清理过期Session的定时任务默认0,到时间自动清理。
    String cleanupCron() default "0 * * * * *";
 
    SaveMode saveMode() default SaveMode.ON_SET_ATTRIBUTE;
}

Controller类文件

前一篇项目源码的基础上,在BootUserController类文件中增加两个方法,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.yoodb.study.demo04;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import com.yoodb.study.demo04.bean.BootUser;
import com.yoodb.study.demo04.service.BootUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import javax.servlet.http.HttpServletRequest;
 
@RestController
@RequestMapping("/myt")
public class BootUserController {
    @Autowired
    private BootUserService service;
 
    @RequestMapping("/getUsers")
    public List<BootUser> getUsers() {
        List<BootUser> list = service.getUsers();
        return list;
    }
 
    @GetMapping(value = "/first")
    public Map<String, Object> firstResp (HttpServletRequest request){
        Map<String, Object> map = new HashMap<>();
        StringBuffer requestUrl = request.getRequestURL();
        request.getSession().setAttribute("requestUrl",requestUrl );
        map.put("requestUrl", requestUrl);
        return map;
    }
 
    @GetMapping(value = "/sessions")
    public Object sessions (HttpServletRequest request){
        Map<String, Object> map = new HashMap<>();
        map.put("sessionId", request.getSession().getId());
        map.put("message", request.getSession().getAttribute("requestUrl"));
        return map;
    }
 
}

Spring Boot项目启动

1、访问8080端口项目启动成功之后测试访问,访问8080端口的first地址:http://localhost:8080/myt/first

返回json结果:

1
{"requestUrl":"http://localhost:8080/myt/first"}

通过redis客户端工具连接redis服务,可以看到redis中已经存在springsession相关数据,此时也可以看到设置的sessions值。

接着,访问8080端口的sessions地址:

http://localhost:8080/myt/sessions

返回json结果:

1
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

2、访问9090端口

配置application.properties文件,请求9090端口的设置,配置信息如下:

1
2
#指定端口号
server.port=9090

项目启动成功之后测试访问,访问9090端口的sessions地址:

http://localhost:9090/myt/sessions

1
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

注:通过返回json结果可以发现8080与9090两个服务返回的数据相同,那么恭喜已经实现了session的共享。

如果此时访问9090端口的first地址,会发现与8080端口的访问地址端口号不相同:

http://localhost:9090/myt/first

返回json结果:

1
{"requestUrl":"http://localhost:9090/myt/first"}

8080和9090端口两个服务的sessions访问地址,都会返回如下json结果:

1
{"sessionId":"3572e134-56b8-42ed-97b8-14620982f8c2","message":"http://localhost:8080/myt/first"}

结论:两个服务的访问地址不相同,但获取的session数据相同,说明已经实现了session共享,与前面说到的登录用户只需要登录验证一次就可以访问所有相互信任的应用系统呼应了。

本文“Spring Boot从入门到精通(七)集成Redis实现Session共享”文章的项目源码(springboot-study-demo04)地址:

https://github.com/yoodb/springboot

Spring Boot集成Redis缓存实现session的共享就是这么简单。虽说简单,但在实际项目开发中还是比较应用广泛的,尤其是在分布式应用方面,通过Redis session共享与nginx负载均衡配合,实现分布式应用。下面大家不妨试一试,有什么疑问欢迎下方留言,看到后小编立马回复!

Spring Boot从入门到精通(七)集成Redis实现Session共享的更多相关文章

  1. Spring Boot从入门到精通(六)集成Redis实现缓存机制

    Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...

  2. Spring Boot从入门到精通(八)日志管理实现和配置信息分析

    Spring Boot对日志的处理,与平时我们处理日志的方式完全一致,它为Java Util Logging.Log4J2和Logback提供了默认配置.对于每种日志都预先配置使用控制台输出和可选的文 ...

  3. Spring Boot从入门到精通(五)多数据源配置实现及源码分析

    多数据源配置在项目软件中是比较常见的开发需求,Spring和Spring Boot中对此都有相应的解决方案可供大家参考.在Spring Boot中,如MyBatis.JdbcTemplate以及Jpa ...

  4. Spring Boot从入门到精通(二)配置GitHub并上传Maven项目

    简单介绍一下GitHub,它是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线,除了Git代码仓库托管 ...

  5. Spring Boot从入门到精通(九)整合Spring Data JPA应用框架

    JPA是什么? JPA全称Java Persistence API,是Sun官方提出的Java持久化规范.是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. ...

  6. Spring Boot从入门到精通(十一)集成Swagger框架,实现自动生成接口文档

    Swagger是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.Swagger 是一组开源项目,其中主要要项目如下: Swagger-tools:提供各种与S ...

  7. 快速开发架构Spring Boot 从入门到精通 附源码

    导读 篇幅较长,干货十足,阅读需花费点时间.珍惜原创,转载请注明出处,谢谢! Spring Boot基础 Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计 ...

  8. Spring Boot从入门到精通(一)搭建第一个Spring Boot程序

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...

  9. Spring Boot 项目实战(四)集成 Redis

    一.前言 上篇介绍了接口文档工具 Swagger 及项目监控工具 JavaMelody 的集成过程,使项目更加健壮.在 JAVA Web 项目某些场景中,我们需要用缓存解决如热点数据访问的性能问题,业 ...

随机推荐

  1. locate及find查找命令

    在文件系统上查找符合条件的文件:       实现工具:locate,find locate:       依赖于事先构建好的索引库:       系统自动实现(周期性任务):       手动更新数 ...

  2. layui从url中取值 ajax获取当前链接中的变量

    在使用layui(javascript)的时候,  需要从当前页面的url地址中取值, 例如: http://localhost:8081/html/fund-purchase.html?fundID ...

  3. 存储映射I/O函数

    1.void  * mmap((void *addr, size_t length, int prot, int flags, int fd, off_t offset) 参数: addr:用于指定映 ...

  4. 在SpringBoot中使用Junit测试

    一:加入依赖 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactI ...

  5. mysql 多字段更新

    更新一个字段当好写 ; Query OK, rows affected (17.36 sec) Rows matched: Changed: Warnings: 问题是想更新多个字段sql serve ...

  6. python-django框架-电商项目-购物车模块开发_20191125

    python-django框架-电商项目-购物车模块开发 商品详情页js代码: 在商品详情页,有加入购物车按钮, 点击加减号可以增加减少,手动输入也可以, 点击加入购物车,就要加过去, 先实现加减的操 ...

  7. Java中的Properties类

    目录 Java中的Properties类 前言 主要方法 读取Properties文件 相关实例 Java中的Properties类 前言 Java中的Properties类属于配置文件,以键值对的方 ...

  8. JavaScript学习总结(八)正则表达式

    转自:http://segmentfault.com/a/1190000000699097 基本概念 正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”) ...

  9. Win10下JDK环境搭建的两种方法

    jdk1.8--64位官网下载的百度网盘 https://pan.baidu.com/s/1A7jYfupwMWZawb5z_RSdJg 提取码:    92eu 第一种方法(建议)    变量名:  ...

  10. 垃圾回收GC

    ​ 每种语言都有自己的垃圾回收机制.接下来我们来讲一下python的垃圾回收机制. 小整数对象池:python对小整数的定义为[-5,257),这些整数对象是提前建立好的,不会被垃圾回收.单个字母也一 ...