一只彩色的熊猫

导航

使用redis实现分布式会话

拦截流程
image

创建受限资源拦截器

@Component   //标注一个类为Spring容器的Bean
public class CheckTokenInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //受限资源拦截器,访问的前提是已经登录,故在此处检查token
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String method = request.getMethod();
        if("OPTIONS".equalsIgnoreCase(method)){
            return true;
        }
        String token = request.getHeader("token");
        if(token == null){
            ResultVO resultVO = new ResultVO(ResStatus.LOGIN_FAIL_NOT, "请先登录!", null);
            doResponse(response,resultVO);
        }else{
            //若有token,则将此token与redis中的token进行对比查找
            String s = stringRedisTemplate.boundValueOps(token).get();
            if(s==null){
                //此token未查找到,两种可能,1、没登录过 2、登录过期了
                ResultVO resultVO = new ResultVO(ResStatus.LOGIN_FAIL_NOT, "请先登录!", null);
                doResponse(response,resultVO);
            }else {
                //在redis中找到了,那么重新调整一下此token的过期时间
                stringRedisTemplate.boundValueOps(token).expire(30, TimeUnit.MINUTES);
                return true;
            }
        }
        return false;
    }

    private void doResponse(HttpServletResponse response,ResultVO resultVO) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        String s = new ObjectMapper().writeValueAsString(resultVO);//将Java对象转为Json格式的数据,用于后端Servlet向AJAX传递Json数据
        out.print(s);
        out.flush();
        out.close();
    }
}

创建非受限资源拦截器

主要负责检测请求中是否含有token,若有token,且此token在redis中存在,则刷新此token的过期时间

//用于拦截非受限资源,若有token则重新设置过期时间
@Component
public class SetTimeInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String method = request.getMethod();
        if("OPTIONS".equalsIgnoreCase(method)){
            return true;
        }
        String token = request.getHeader("token");
        if(token!=null){
            String s = stringRedisTemplate.boundValueOps(token).get();
            if(s!=null){
                stringRedisTemplate.boundValueOps(token).expire(30, TimeUnit.MINUTES);
            }
        }
        //此拦截器负责给token延长过期时间(有token且redis中找得到就延长,没有token就不延长),因此无论如何都是返回true
        return true;
    }
}

配置拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private CheckTokenInterceptor checkTokenInterceptor;

    @Autowired
    private SetTimeInterceptor setTimeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截受限资源路径(访问条件:已登录)
        registry.addInterceptor(checkTokenInterceptor)
                .addPathPatterns("/shopcart/**")
                .addPathPatterns("/orders/**")
                .addPathPatterns("/useraddr/**")
                .excludePathPatterns("/user/**");
        //拦截所有资源路径(主要是为了拦截非限制资源)
        registry.addInterceptor(setTimeInterceptor).addPathPatterns("/**");
    }
}

posted on 2021-07-29 21:55  一只彩色的熊猫  阅读(199)  评论(0编辑  收藏  举报