今天做了个小项目,使用自定义一个拦截器后使用redisTemplate获取redis缓存数据一直报null空指针。
随后使用了debug模式查找问题,发现token值获取到了,且redis中存在该缓存,但获取的还是null。
查看了代码发现没有什么问题:
//如果未登陆 直接访问某个地址时
public class AuthcFilter extends FormAuthenticationFilter {
@Autowired
private RedisTemplate redisTemplate;
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
//对OPTION请求方式放行 其他的请求方式都拦截。
HttpServletRequest req= (HttpServletRequest) request;
HttpServletResponse resp= (HttpServletResponse) response;
String method = req.getMethod();
if(RequestMethod.OPTIONS.name().equals(method)){
return true;
}
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest req= (HttpServletRequest) request;
HttpServletResponse resp= (HttpServletResponse) response;
String token = req.getHeader("token");
Object o = redisTemplate.opsForValue().get(token);
if(StringUtils.isBlank(token) || o==null){
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setCharacterEncoding("UTF-8");
CommonResult result=new CommonResult();
result.setCode(5000);
result.setMsg("请先登陆");
String json = JSON.toJSONString(request);
httpResponse.getWriter().print(json);
return false;
}
return true;
}
}
这时我才想起来,过滤器或拦截器在生效时,比你的注入要更快,导致redisTemplate还没注入就使用所以会报空指针异常。
解决方法:自定义一个工具类,,让它在注入容器时就生效,在拦截器中只需要使用该工具类即可
@Component //项目运行时就注入Spring容器
public class RedisUtils {
@Resource
private RedisTemplate<String, Object> redis;
//赋值一个静态的redisTemplate
public static RedisTemplate redisTemplate;
@PostConstruct //此注解表示构造时赋值
public void redisTemplate() {
redisTemplate = this.redis;
}
}
此时项目中只需要使用RedisUtils中的redisTemplate即可。
String token = req.getHeader("token");
Object o = RedisUtils.redisTemplate.opsForValue().get(token);