发布时间: 阅读量

SpringBoot 拦截器 redis注入为null

拦截器中注入实例为null

前言,项目在做登陆功能是有用到redis,在用户登陆成功后,讲生成的token放入redis,并设置过期时间,然后配置拦截器,对所有路径拦截,判断是否携带有效token!这时需要在自定义的拦截器中注入redis,跑项目的时候发现总是注入的实例为null,原因就在这里


话不多说,见代码

1.首先是我自定义的拦截器

import cn.hutool.json.JSONObject;
import com.gistone.risk.util.RedisUtil;
import com.gistone.risk.vo.ResultVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zf1017@foxmail.com
 * @date 2019/7/25 0025 10:39
 * @description
 */

public class SysUserLoginInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        Object accessToken = getCookieByName(request, "token") != null ? getCookieByName(request, "token").getValue() : null;
        Object idKey = getCookieByName(request, "id") != null ? getCookieByName(request, "id").getValue() : null;
        if(accessToken==null){
            returnJson(response, "token为空");
            return false;
        }
        if(idKey==null){
            returnJson(response, "id为空");
            return false;
        }
        String values =redisTemplate.opsForValue().get(idKey);
        if(!accessToken.equals(values)){
            returnJson(response, "无效token");
        }


        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {

    }

    /**
     * 根据名字获取cookie
     *
     * @param request
     * @param name    cookie名字
     * @return
     */
    public static Cookie getCookieByName(HttpServletRequest request, String name) {
        Map<String, Cookie> cookieMap = ReadCookieMap(request);
        if (cookieMap.containsKey(name)) {
            Cookie cookie = (Cookie) cookieMap.get(name);
            return cookie;
        } else {
            return null;
        }
    }

    /**
     * 将cookie封装到Map里面
     *
     * @param request
     * @return
     */
    private static Map<String, Cookie> ReadCookieMap(HttpServletRequest request) {
        Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                cookieMap.put(cookie.getName(), cookie);
            }
        }
        return cookieMap;
    }

    /**
     * 异常返回
     * @param response
     * @param json
     * @throws Exception
     */
    private void returnJson(HttpServletResponse response, String json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        try {
            writer = response.getWriter();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", 211);
            jsonObject.put("msg",json);
            /*Map<String, Object> map = new HashMap<>();
            map.put("status", 0);
            map.put("mesg",json);*/
            writer.print(jsonObject);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null)
                writer.close();
        }
    }

}

2.配置类

import com.gistone.risk.interceptor.SysUserLoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author zf1017@foxmail.com
 * @date 2019/7/25 0025 10:27
 * @description
 */

@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    /**
     * 自己定义的拦截器类
     * @return
     */
    @Bean
    SysUserLoginInterceptor sysUserLoginInterceptor() {
        return new SysUserLoginInterceptor();
    }
    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sysUserLoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/risk/login/check").excludePathPatterns("/risk/index.html").
                        excludePathPatterns("/risk/img/**").excludePathPatterns("/risk/css/**")
                .excludePathPatterns("/risk/js/**").excludePathPatterns("/risk/fonts/**");
    }

}

3.下面说一下,之前为什么没有生效
wei-xin-tu-pian-_20190729144218

4.改正以后的如下图
wei-xin-tu-pian-_20190729150635

至此拦截器中的redis注入问题解决,原因:造成null的原因是因为拦截器加载是在springcontext创建之前完成的,所以在拦截器中注入实体自然null


后续,问题是解决了,但是具体是什么原理搞定的,还不是很清楚,大概就是因为,加载的顺序引起的,等研究明白再补充

这篇文章比较好