问题复现
在springboot用Filter+redis做token验证,但在拦截后连接redis时始终出现空指针异常,判断为RedisTemplate没有注入,报错如下
原始代码为:
@WebFilter(filterName = "Myfilter",urlPatterns = "*.do")
@Order(1)
@CrossOrigin(origins = "*",maxAge = 3600,allowedHeaders = "*")
public class Myfilter implements Filter {
@Autowired
private static RedisTemplate redisTemplate;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("--------Filter过滤器init---------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//-------------从请求头获取token---------------
String user_no=null;
System.out.println("------doFilter-------");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setCharacterEncoding("utf-8");
String token = request.getHeader("token");
String uri = request.getRequestURI();
System.out.println("-------token="+token+"----------uri="+uri);
DataGridResult dataGridResult = new DataGridResult();
ObjectMapper objectMapper = new ObjectMapper();
if (!"/mgr/login.do".equals(uri) && !"/uploadfile.do".equals(uri)){
if (token==null || "".equals(token) || token.indexOf(";")==-1){//没有token
System.out.println("----没有token或者错误的token格式----");
dataGridResult.setCode(Constants.TOKEN_BAD);
dataGridResult.setMsg("没有token或者错误的token格式");
String json = objectMapper.writeValueAsString(dataGridResult);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
// response.sendRedirect("/TokenBad.html");
return;
}
//有token则验证token是否正确
user_no = "mgr" + token.substring(1,token.indexOf(";"));
System.out.println(user_no);
String comeToken = token.substring(token.indexOf(";")+1,token.length()-1);
ValueOperations valueOperations = redisTemplate.opsForValue();
String realToken = (String) valueOperations.get(user_no);
System.out.println(user_no+"----"+comeToken+"---"+realToken);
//没查到对应的token
if (realToken == null || "".equals(realToken)){
System.out.println("-----token过期或用户未登陆过,请重新登录-----------");
dataGridResult.setCode(Constants.TOKEN_BAD);
dataGridResult.setMsg("token过期或用户未登陆过,请重新登录");
String json = objectMapper.writeValueAsString(dataGridResult);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
// response.sendRedirect("/TokenBad.html");
return;
}
//token错误
if (!realToken.equals(comeToken)){//如果不正确
System.out.println("---token错误或此用户未登陆过-----------");
dataGridResult.setCode(Constants.TOKEN_BAD);
dataGridResult.setMsg("token错误或此用户未登陆过");
String json = objectMapper.writeValueAsString(dataGridResult);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
// response.sendRedirect("/TokenBad.html");
return;
}
}
if (user_no!=null && !"".equals(user_no)){//除开login、logout的情况
redisTemplate.expire(user_no,60*30, TimeUnit.SECONDS);//验证成功,则从新计时30分钟
System.out.println("----token正确,token生命重新计时------");
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("--------Filter过滤器destroy---------");
}
}
各种查阅资料和排查后,解决问题,方法如下:
【注】!!!
还要在properties或yml下加入redis的相关配置(ip、账户密码等),否则会默认链接本地的6379端口,而后报错。