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

1 篇文章 0 订阅
1 篇文章 0 订阅

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");   // 放行
    }
}

自定义的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);
    }
}

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");   // 放行
    }
}

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值