AOP实现上下文存储 --- 系统框架搭建(三)

前面我们说了redis实现单点登入和redis实现登录拦截,redis实现登入拦截可以和session一起连用,保证用户必须在登入的条件下,才可以进行网站的访问。

springBoot+redis实现登入拦截器--系统框架搭建(二)icon-default.png?t=L892https://blog.csdn.net/ke1ying/article/details/117822312?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163169761016780261969297%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163169761016780261969297&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-12-117822312.pc_v2_rank_blog_default&utm_term=%E7%B3%BB%E7%BB%9F

1、项目需求

这篇文章介绍如何获取到我们需要的连接上下文信息,比如用户信息,可以存储一个全局变量,直接获取,这样在我们每次访问数据库的时候都可以获取到用户信息等我们需要的数据。这里需要注意的地方是,为了防止不同的用户登入存储出现线程不安全情况,所以有threalLocal来保存不同用户的信息,使用threalLocal的时候记得要remove掉缓存。

另外当有其他网站调用我们系统的时候,会出现没有登入人的情况,这时候可以用spring源码的接口InitializingBean在spring容器创建的时候,给我们当前系统默认登入管理员。

2、代码实例

先定义一个放上下文的util和实体类:


/**
 * 全文上下文
 *
 * @author keying
 */
public class ContextUtil implements InitializingBean {

    private static Context systemContext = new Context();

    private static ThreadLocal<Context> threadLocalContext = new ThreadLocal<>();

    public static Context getContext() {
        return threadLocalContext.get();
    }

    public static void setContext(Context context) {
        threadLocalContext.set(context);
    }

    public static void removeContext() {
        threadLocalContext.remove();
    }

    public static Context getSystemContext(){
        return systemContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        systemContext.setUserId("admin");
    }
}

/**
 * 上下文
 *
 * @author keying
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Context {

    private String userId;
}

然后定义一个拦截器,拦截器里有我上篇文章redis实现单点登入的代码,已注释:


/**
 * 登入拦截器
 *
 * @author keying
 * @date 2021/6/11
 */
@Configuration
@Slf4j
public class LoginConfiguration implements WebMvcConfigurer {

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
               /* log.info("登入拦截器启动!!");
                log.info("session是否存在:{}", request.getSession().getAttribute("name"));
                if (request.getSession().getAttribute("name") != null) {
                    redisTemplate.opsForValue().set("name", request.getSession().getAttribute("name"), 10,TimeUnit.SECONDS);
                    return true;
                }
                log.info("request.getContextPath():{}", request.getContextPath());
                response.sendRedirect(request.getContextPath() + "/redis/single/system1");
                //如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
                //如果设置为true时,请求将会继续执行后面的操作
                return false;*/
                return true;
            }

            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
                log.info("postHandle");
            }

            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) throws Exception {
                log.info("afterCompletion");
            }
        });
        //所有路径都被拦截
       /* interceptorRegistration.addPathPatterns("/**");*/
        //添加不拦截路径
        interceptorRegistration.excludePathPatterns(
            //"/redis/single/login_page",
            "/redis/single/system1",
            "/redis/single/system2",
            "/redis/single/detection",
            "/**/*.html",
            "/**/*.js",
            "/**/*.css",
            "/**/*.woff",
            "/**/*.ttf"
        );

        interceptorRegistration = registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
                //加上下文
                Context context = getContext();
                ContextUtil.setContext(context);
                return true;
            }

            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) throws Exception {
                //一定要记得remove
                ContextUtil.removeContext();
            }
        });

        //拦截所有路径
        interceptorRegistration.addPathPatterns("/**");

    }

    private Context getContext() {
        //给一个虚拟的登入者
        return new Context("keying");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端从入门到精通

你的鼓励是我最大的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值