(一)ThreadLocal
动态的获取信息
1 需求分析
如果将用户信息保存到?Session域中,那么需要在Controller方法中必须添加request对象.
但是想在任何地方获取用户信息应该怎么办??
解决方案: ThreadLocal
2 功能原理
ThreadLocal(本地线程变量)在一个线程内,实现数据的共享,线程是安全的.
但是使用它的时候一定要记得释放资源,因为GC回收不了它.如果不释放的话,会造成内存泄漏.
3 工具类代码
public class UserThreadLocal { private static ThreadLocal<User> userThread = new ThreadLocal<>(); public static void set(User user){ userThread.set(user); } public static User get(){ return userThread.get(); } //防止内存泄漏 public static void remove(){ userThread.remove(); } }
(二)实现单点登录流程
1 需求分析
根据分布式的思想,需要将服务进行拆分.拆分完成后为了抗击高并发,搭建tomcat服务器集群.但是现在遇到的问题是,用户访问系统时需要频繁地登录.
2 解决方案
问题:如果用户没有登录,则不允许执行敏感操作(查询订单/查询物流)
因为采用集群的搭建方式,所以session不能共享.
解决:(以上图为例)
- 当用户输入用户名和密码后点击登录按钮后,系统访问jt-web
- jt-web接收用户的数据后经过加密处理后,请求JT-SSO进行数据校验
- JT-SSO接收请求后,进行用户信息的校验.如果根据数据查询,用户不存在,用户输入的用户名或者密码错误,则直接返回错误提示(state:201). 如果用户名和密码正确,则开始实现单点登录.
- 生成加密的秘钥TOKEN,之后将user数据转化为userJSON数据,将数据保存到redis中.token充当key,userJSON充当value.
- JT-SSO将用户登录的秘钥token返回给JT-WEB
- JT-WEB将token数据返回给用户,将token数据保存到用户浏览器的cookie中
- 如果用户再次访问JT-WEB时,获取cookie中的TOKEN,查询Redis缓存服务器.如果有数据,则证明用户已经登录.则进行数据回显.如果用户返回数据为null,表示没有登录.则根据具体的业务实现再定.
功成名就不是目的,让自己快乐,这才是生活的意义.