原因:拦截器在bean初始化前执行的,这时候redisUtil是null,需要通过下面这个方式去获取
主要解决的代码:
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
redisOpsUtil = wac.getBean(RedisOpsUtil.class);
package com.hzh.studyonline.config;
import com.hzh.studyonline.util.JwtUtil;
import com.hzh.studyonline.util.RedisOpsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
//新建拦截器,在token验证前执行
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
RedisOpsUtil redisOpsUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
String phone = request.getHeader("phone");
// 如果不是映射到方法直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
//如果接口或者类上有@JwtIgnore注解,意思该接口不需要token就能访问,需要放行
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
//先从类上获取该注解,判断类上是否加了@JwtIgnore ,代表不需要token,直接放行
JwtIgnore annotation = handlerMethod.getBeanType().getAnnotation(JwtIgnore.class);
if(annotation == null){
//再从方法上获取该注解
if(method.isAnnotationPresent(JwtIgnore.class)){
annotation = method.getAnnotation(JwtIgnore.class);
log.info("请求方法 {} 上有注解 {} ",method.getName(),annotation);
}
}
if (annotation!=null){
return true;
}
//开始检验没有权限的接口
//1、jwt解析正确
JwtUtil jwtUtil = new JwtUtil();
boolean parse = jwtUtil.parse(token);
//2、从redis中获取的token一致
if (redisOpsUtil==null){
//拦截器在bean初始化前执行的,这时候redisUtil是null,需要通过下面这个方式去获取
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
redisOpsUtil = wac.getBean(RedisOpsUtil.class);
}
String redisToken =(String) redisOpsUtil.hget("token", phone);
if (redisToken==null){
log.info("redisToken过期 电话是:{} 的用户 ",phone);
return false;
}
if (parse==true && redisToken.equals(token)){
return true;
}
return false;
}
}