spring如何共享controller里面的session?

这个问题源于验证码的获取与验证,在AController里面获取生成验证码,放到session,如何在BController里面获取?

阅读 6.7k
5 个回答

这个问题的话,如果是单服务器,单应用,在 Spring Boot 中可以这样写 Controller:

根据题主的问题,我这里定义两个 Controller:

  • SetController: 生成验证码
  • GetController: 验证验证码

SetController.java

@RestController
public class SetController {

    @GetMapping(value = "/set")
    public String setAttribute(HttpSession session) {

        String uuid = UUID.randomUUID().toString();
        session.setAttribute("uuid", uuid);

        return uuid;
    }

}

GetController.java

@RestController
public class GetController {

    @GetMapping("/get")
    public String getAttribute(HttpSession session) {

        return (String) session.getAttribute("uuid");

    }
}

上述两个简单的 Controller 演示了在 Spring 中如何存储和读取 Session 中的内容。

如果是单应用,多服务器的话,我能想到的有以下两种解决方案:

1. 使用 Spring Session 分布式存储 Session

  • 应用配置配置文件(yaml 格式)
# 使用 Redis 存储分布式会话
spring:
  session:
    store-type: redis
  • 注入相关的 Bean
@Configuration
@EnableRedisHttpSession
public class SpringSessionConfig {

    @Bean
    public JedisConnectionFactory connectionFactory() {
        return new JedisConnectionFactory();
    }

}

这种方式,之前的代码不需要有任何改变,往 Session 中读取和存入属性依然使用 getAttrubite(key)setAttribute(key, value) 方法,Spring Session 把分布式会话透明化了。

2. 使用 Redis + Token

  • 为每次会话生成一个唯一的 key 作为会话 ID
  • 为该会话 ID 生成会话对象
  • 为会话对象存储验证码
  • 会话对象存储在 Redis 中
  • 验证验证码时,将唯一的 key 作为 Token,通过 HTTP 首部或者 Cookie 中发送请求
  • 服务器端,解析请求,从 Redis 中读取对应 key 的验证码

当然,第二种方式是自己手动维护了一个 Session 机制,还有会话过期、令牌回收、有效性检查等多方面因素,需谨慎考虑。

新手上路,请多包涵

HttpServletRequest req
req.getSession().getAttribute();

只要sessionId一致就可以访问到相应session里面的数据

当客户端第一访问服务器的时候,服务器会返回一个sessionId,一般浏览器会使用cookie自动保存sessionId,然后下次请求的时候把这个sessionId带上,就可以获取该sessionId对应的session的数据,也就可以这样获取数据

HttpServletRequest req;
req.getSession().getAttribute();

验证码不建议存放于Session中,可以考虑存于Redis 或者memcached中

不同请求session是不一样的,当然获取不到,看下Spring Session

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题