Spring Session使用

一.使用场景

前后端不分离的情况下,往登陆页auth.gulimall.com的session中存放一个用户信息,想要在首页gulimall.com中取出该数据并展示出来

 	@GetMapping("/oauth2.0/gitee/success")
    public String oauth2(@RequestParam("code") String code, HttpSession httpSession) throws Exception {
		......
		if (r.getCode() == 0){
                MemberOAuthVo memberOAuthVo = r.getData(new TypeReference<MemberOAuthVo>() {});
                log.info("用户信息:{}",memberOAuthVo);
                httpSession.setAttribute("loginUser",memberOAuthVo);
                return "redirect:http://gulimall.com";
	     }
	    ......
    }

首页
在这里插入图片描述

二.session不共享的原因

1. 如果想要取出session数据需要通过Cookie的JSESSIONIDDomain,这里的Domain规定了session可以在那些域名下面使用,每一个域名下的的Domain是不同的,这就导致域名a的数据不能被域名b拿到

在这里插入图片描述
在这里插入图片描述

2. 并且session是存放在服务器内存中,如果是一个服务多实例的情况,那么每个服务器的内存也是无法共享session的

三.解决方法

1. 解决不同域名无法共享session的问题

放大JSESSIONID的DOMAIN作用域,实战中不可能手动修改DOMAIN范围,使用springsession解决 auth.gulimall.com -> .gulimall.com

2. 解决分布式服务(同服务不同实例)不共享session的问题

将session存在redis中

四.导入Spring Session

1.导入依赖(存的服务和取的服务都需要配置一份 )

        
        <dependency>
            <groupId>org.springframework.sessiongroupId>
            <artifactId>spring-session-data-redisartifactId>
        dependency>

2.application.properties

#session存储类型
spring.session.store-type=redis
#session过期时间: 默认30分钟
server.servlet.session.timeout=30

3.启动类添加注解

自动将HttpSession中的数据存入redis,原来HttpSession源码是从currentMap内存中存取session,现在是从包装后的wrappedRequest取session,也是从redis上操作存和取session

@EnableRedisHttpSession

@EnableRedisHttpSession导入RedisHttpSessionConfiguration配置,给容器中添加了一个组件
RedisOperationsSessionRepository:Redis操作session,session的增删改查封装类

4.自定义配置类

解决Domain子域名无法获取session数据的问题

@Configuration
public class GulimallSessionConfig {

    /**
     * 自定义session的使用范围——Domain
     */
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setDomainName("gulimall.com");
        defaultCookieSerializer.setCookieName("GULISESSION");
        return defaultCookieSerializer;
    }

    /**  
     * 自定义redis序列化方式为json,原来是Serializable
     */
    @Bean
    public RedisSerializer<Object> redisSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }
}

5.前端取值展示

<li style="width: 100px;">
	<a th:if="${session.loginUser != null}">欢迎, [[${session.loginUser.username}]]a>
	<a th:if="${session.loginUser == null}" href="http://auth.gulimall.com/login.html">你好,请登录a>
li>
<li>
	<a th:if="${session.loginUser == null}" href="http://auth.gulimall.com/reg.html" class="li_2">免费注册a>
li>

五. 实现效果

首页
在这里插入图片描述
点击登陆 —> 授权成功 —> 获取用户信息 —> 用户信息存入session
在这里插入图片描述

在登录页与主页不同域名的情况下,登陆页授权成功往session中存入用户信息,跳转至首页 ,首页取出session中用户名并展示
在这里插入图片描述

你可能感兴趣的:(spring,java,后端)