• SpringBoot项目中Interceptor拦截器中使用@Autowired注解,运行时会报错空指针


    SpringBoot项目中Interceptor拦截器中使用@Autowired注解,运行时会报错空指针

    1.问题描述

    今天新建一个springboot的demo项目,想在interceptor中更新用户token信息,但是在使用过程中,报错服务类对象为null空指针异常,具体代码如下,userService对象为空,具体原因是因为拦截器在其配置类自定义WebMvcConfigurer里是使用new创建的,而使用new创建的类就不归spring管理了,所以在里面使用@Autowired也将报错,配置类代码如下,即 registry.addInterceptor( new PermisssionInterceptor() ) 这一段,参数是new一个对象

    @Configuration
    public class PermissionWebConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor( new PermisssionInterceptor() )
                    .addPathPatterns("/**")    // 拦截页面
                    .excludePathPatterns("/user/login", "/user/register");   // 放行
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    自定义的Interceptor类如下:

    /**
     * 拦截需要授权的接口
     */
    @Slf4j
    public class PermisssionInterceptor implements HandlerInterceptor {
    
        @Autowired
        private UserService userService;
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 检查用户JWT
            String jwt = request.getHeader("access-token");
            // 校验并取出私有信息
            try {
                if ("".equals(jwt) || null == jwt) {
                    throw new CommException("请您先登录");
                }
                // token 解码
                DecodedJWT dj = JwtUtil.decodeToken(jwt);
                // 取出基本用户信息加入请求头
                String userId = dj.getClaim("userId").asString();
                String userName = dj.getClaim("userName").asString();
                // jwt校验合格的,将 jwt 中存的用户信息加入请求头,不合格的,请求头存个空用户
                request.setAttribute("jwt-user", userId != null ? new User(Integer.valueOf(userId), userName) : new User());
                // 计算当前时间是否超过过期时间的一半,如果是就帮用户续签
                Long expTime = dj.getExpiresAt().getTime();
                Long iatTime = dj.getIssuedAt().getTime();
                Long nowTime = new Date().getTime();
                if ((nowTime - iatTime) > (expTime - iatTime) / 2) {
                    // 生成新的jwt
                    Map<String, String> payload = new HashMap<>();
                    payload.put("userId", userId); // 加入一些非敏感的用户信息
                    payload.put("userName", userName);    // 加入一些非敏感的用户信息
                    String newJwt = JwtUtil.generateToken(payload);
                    // 加入返回头
                    response.addHeader("access-token", newJwt);
                    userService.updateToken(userId, userName, newJwt);
                }
                return true;
            } catch (JWTDecodeException e) {
                log.error("token令牌错误");
                throw new CommException("token令牌错误");
            } catch (TokenExpiredException e) {
                log.error("token令牌过期");
                throw new CommException("token令牌过期");
            }
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    2.解决办法

    解决办法有两种,这里参考大神的博客使用其中一种,即直接在WebMvcConfigure类中添加经由@Bean注解的返回拦截器对象的方法,修改后的PermissionWebConfig类如下:

    @Configuration
    public class PermissionWebConfig implements WebMvcConfigurer {
        @Bean
        public HandlerInterceptor getPermisssionInterceptor(){
            return new PermisssionInterceptor();
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(getPermisssionInterceptor())
                    .addPathPatterns("/**")    // 拦截页面
                    .excludePathPatterns("/user/login", "/user/register");   // 放行
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这样问题就可以解决,感谢网络大神!
    @https://blog.csdn.net/wangdawei_/article/details/122008669

  • 相关阅读:
    【C语言】指针详解(3)
    种草模式崛起!小红书KOL达人种草成推广热门方向!
    中心化决议管理——云端分析
    docker 更新升级 nginx
    Linux文件/目录高级管理二
    将 BA、DevOps 和 QA 与云测试同步
    【ACM学习】【STL】关联容器的分类
    Java知识梳理 第十二章 常用类
    PHP 8 MySQL 教程:构建登录和用户身份验证系统
    UE TransformVector 学习笔记
  • 原文地址:https://blog.csdn.net/qq_23859799/article/details/126752408