Spring中的Interceptor拦截器中使用@Autowired注解,在运行时会出现空指针

问题描述

我们一般在拦截器中会写一些逻辑处理,比如获取用户的登录信息,将信息存入ThreadLocal等等。
而获取用户信息的时候就有多种方式了。
比如:在session中获取,或者使用token去redis中获取。
这个问题就是使用token去redis中获取用户信息的时候遇到的。因为在获取时需要使用@Autowired将StringRedisTemplate注入。此时运行就遇到了空指针错误。

原因分析

原因:因为拦截器在其配置类里是使用new创建的,而使用new创建的类就不归spring管理了,所以在里面使用@Autowired也将报错。
配置类代码如下:

1 @Configuration
2 public class WebMvcConfig implements WebMvcConfigurer {
3     @Override
4     public void addInterceptors(InterceptorRegistry registry) {
5         registry.addInterceptor(new CustomerInterceptor()).addPathPatterns("/customer/**");
6         registry.addInterceptor(new ManageInterceptor()).addPathPatterns("/manage/**");
7 
8     }
9 }

解决方案:

方案一:

将拦截器类中添加@Component注解,然后在WebMvcConfigure类中使用@Autowird,将拦截器对象注入进来
代码如下:

 1 @Component
 2 public class CustomerInterceptor extends HandlerInterceptorAdapter {
 3     @Autowired
 4     private StringRedisTemplate stringRedisTemplate ;
 5     @Override
 6     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 7         String token = request.getHeader("accessToken");
 8         if (token == null){
 9             PrintWriter out = response.getWriter();
10             out.print(JSON.toJSON(ResultUtil.error("请进行登录")));
11             return false;
12         }
13         if (TokenUtils.verify(token)){
14             JSONObject object = JSONObject.fromObject(stringRedisTemplate.opsForValue().get(token));
15 
16             CustomerVo msg = (CustomerVo)JSONObject.toBean(object, CustomerVo.class);
17 
18             CustomerThreadLocal.set(msg);
19             if (msg!=null){
20                 return true;
21             }
22         }
23         return false;
24     }
25 
26     @Override
27     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
28 
29     }
30 
31     @Override
32     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
33 
34     }
35 }
 1 @Configuration
 2 public class WebMvcConfig implements WebMvcConfigurer {
 3     @Autowired
 4     CustomerInterceptor customerInterceptor;
 5     @Autowired
 6     ManageInterceptor manageInterceptor;
 7     @Override
 8     public void addInterceptors(InterceptorRegistry registry) {
 9         registry.addInterceptor(customerInterceptor).addPathPatterns("/customer/**");
10         registry.addInterceptor(manageInterceptor).addPathPatterns("/manage/**");
11 
12     }
13 }

方案二:

无需在拦截器类上添加@Component直接,直接在WebMvcConfigure类中添加经由@Bean注解的返回拦截器对象的方法。
代码:

 1 @Configuration
 2 public class WebMvcConfig implements WebMvcConfigurer {
 3 
 4     @Bean
 5     public CustomerInterceptor customerInterceptor(){
 6         return new CustomerInterceptor();
 7     }
 8     @Bean
 9     public ManageInterceptor manageInterceptor(){
10         return new ManageInterceptor();
11     }
12     @Override
13     public void addInterceptors(InterceptorRegistry registry) {
14         registry.addInterceptor(customerInterceptor()).addPathPatterns("/customer/**");
15         registry.addInterceptor(manageInterceptor()).addPathPatterns("/manage/**");
16 
17     }
18 }

 

posted @ 2022-07-05 20:40  Boblim  阅读(458)  评论(0编辑  收藏  举报