欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot中添加拦截器,在拦截器中注入其他类的时候出现空指针异常解决办法

程序员文章站 2022-04-16 08:53:37
...

拦截器代码

/**
 *
 * 记录用户轨迹
 */
@Component
public class AdminInterceptor implements HandlerInterceptor {

    @Autowired
    SysLogDao sysLogDao

    /**
     * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
     */

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行了AdminInterceptor的afterCompletion方法");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss");
        LocalDateTime now = LocalDateTime.now();
        Object user = request.getSession().getAttribute("userName");
        Object msg = request.getSession().getAttribute("msg");
        if (user != null && msg != null) {
            SysLog sysLog = new SysLog();
            sysLog.setLogId(IDUtils.getId());
            sysLog.setUserName(user.toString());
            sysLog.setMsg(msg.toString());
            sysLog.setCreateTime(dateTimeFormatter.format(now));
            SysLog save = sysLogDao.save(sysLog);
        }

    }
}

注入拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //静态资源:*.css  *.js
        //Spring Boot 已经做好了静态资源映射
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new AdminInterceptor());
        interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
    }
}

调用接口时发现,SysLogDao 并没有被注入进来!明明代码写的没问题,为什么不能正常注入SysLogDao 呢?

仔细观察我们自定义的配置类WebConfig ,在添加拦截器的时候用的是new AdminInterceptor(),如果想要拦截器生效,必须将拦截器配置到WebMvc的配置类中,就是我们自定义的WebConfig 类。现在添加拦截器的时候是 new 了一个拦截器,也就是说并没有将拦截器托管给IOC容器,拦截器加载是在springcontext创建之前完成的,所以就无法引入Spring的bean对象。

解决办法:让Bean对象提前加载,将拦截器注入进来。
方式一:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    public AdminInterceptor adminInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //静态资源:*.css  *.js
        //Spring Boot 已经做好了静态资源映射
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(adminInterceptor);
        interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
    }
}

方式二:
拦截器无需增加@Component注解,在WebConfiguration类中使用@Bean注解将拦截器注成bean。

/**
 *
 * 登录检查
 * 记录用户轨迹
 */
public class AdminInterceptor implements HandlerInterceptor {
...
}
@Configuration
public class WebConfig implements WebMvcConfigurer {

     @Bean
    public AdminInterceptor adminInterceptor(){
        return new AdminInterceptor();
   }
  
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //静态资源:*.css  *.js
        //Spring Boot 已经做好了静态资源映射
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(adminInterceptor());
        interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
    }
}