单点登录(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. Metric space,open set

    目录 引入:绝对值 度量空间 Example: 开集,闭集 引入:绝对值 distance\(:|a-b|\) properties\(:(1)|x| \geq 0\),for all \(x \in ...

  2. 【学习笔记】 Johnson 全源最短路

    前置扯淡 一年多前学的最短路,当时就会了几个名词的拼写,啥也没想过 几个月之前,听说了"全源最短路"这个东西,当时也没说学一下,现在补一下(感觉实在是没啥用) 介绍 由于\(spf ...

  3. 3.redis kyes命令

    Keys命令 1.1设置key的生存时间 Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁. EXPIRE key seconds         ...

  4. spring-boot jpa mysql emoji utfmb4 异常处理

    spring-boot jpa mysql utf8mb4 emoji 写入失败 mysql database,table,column 默认为utf8mb4 Caused by: java.sql. ...

  5. PyCharm4.5 中文破解版破解步骤

    1.在下载之家下载PyCharm4.5中文版软件包,然后右击软件安装包选择解压到“pycharm4.5.3”. 2.在解压文件夹中找到pycharm-professional-4.5.3,右击打开. ...

  6. selenium元素定位(一)

    Selenium提供了8种定位方式. id name class name tag name link text partial link text xpath css selector 这8种定位方 ...

  7. 密码子演化假说|凝固事件假说|立体化学假说|共进化假说|代谢途径相关性假说|四重兼并|假四重兼并|最小损伤原则|AU-rich|GC-rich|逐步进化假说|分子机制进化假说

    生命组学 将密码子表重排后发现,嘌呤嘧啶含量不同,密码子的氨基酸种类由第一二位决定,同时第三位变化大却没有蛋白质层面上实质性的改变,这说明第三位氨基酸是用于维持氨基酸组成不发生变化同时保证蛋白质稳定性 ...

  8. [SDOI2006] 线性方程组

    洛谷 P2455 传送门 刚开始写了个消成上三角的,结果狂wa. 后来经过研究发现,消成上三角那种不能直接判断无解或无穷多解,需要其它的操作. 所以干脆学了个消成对角线的,写了一发A了. 其实两种消元 ...

  9. Nginx笔记总结十九:nginx + fancy实现漂亮的索引目录

    编译:./configure --prefix=/usr/local/nginx --add-module=../ngx-fancyindex-master 配置: location / { fanc ...

  10. Spring Boot中application.properties和application.yml文件

    application.properties和application.yml文件可以放在一下四个位置: 外置,在相对于应用程序运行目录的/congfig子目录里. 外置,在应用程序运行的目录里 内置, ...