Spring--解决拦截器中注入Bean失败的问题

时间:2025-04-28 09:22:54

原文网址:Spring--解决拦截器中注入Bean失败的问题_IT利刃出鞘的博客-****博客

简介

说明

本文用示例介绍如何解决拦截器中注入Bean失败的问题。

场景

Token拦截器中需要用@Autowired注入JavaJwtUtil类,结果发现注入的JavaJwtUtil为Null。

原因

拦截器的配置类是以new JwtInterceptor的方式使用的,那么这个JwtInterceptor不受Spring管理。因此,里边@Autowired注入JavaJwtUtil是不会注入进去的。

问题重现

代码

server:
  port: 8080
spring:
  application:
    name: springboot-jwt
config:
  jwt:
    # 密钥
    secret: abcd1234
    # token过期时间(5分钟)。单位:毫秒.
    expire: 300000

拦截器配置

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        (new JwtInterceptor());
    }
}

拦截器

package ;

import ;
import .slf4j.Slf4j;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    private JavaJwtUtil javaJwtUtil;

    List<String> whiteList = (
            "/auth/login",
            "/error"
    );

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }


        //放过不需要验证的页面。
        String uri = ();
        if ((uri)) {
            return true;
        }

        // 头部和参数都查看一下是否有token
        String token = ("token");
        if ((token)) {
            token = ("token");
            if ((token)) {
                throw new RuntimeException("token是空的");
            }
        }

        if (!(token)) {
            ("token无效");
            return false;
        }

        String userId = (token);
        ("userId:" + userId);
        String userName = (token);
        ("userName:" + userName);
        return true;
    }
}

Jwt工具类

package ;

import com.;
import com.;
import com.;
import com.;
import com.;
import com.;
import ;
import ;

import ;

@Component
public class JavaJwtUtil {
    //过期时间
    @Value("${}")
    private Long EXPIRE_TIME;

    //密钥
    @Value("${}")
    private String SECRET;

    // 生成Token,五分钟后过期
    public String createToken(String userId) {
        try {
            Date date = new Date(() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            return ()
                    // 将 user id 保存到 token 里面
                    .withAudience(userId)
                    // date之后,token过期
                    .withExpiresAt(date)
                    // token 的密钥
                    .sign(algorithm);
        } catch (Exception e) {
            return null;
        }
    }

    // 根据token获取userId
    public String getUserIdByToken(String token) {
        try {
            String userId = (token).getAudience().get(0);
            return userId;
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    // 根据token获取userName
    public String getUserNameByToken(String token) {
        try {
            String userName = (token).getSubject();
            return userName;
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    //校验token
    public boolean verifyToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = (algorithm)
                    // .withIssuer("auth0")
                    // .withClaim("username", username)
                    .build();
            DecodedJWT jwt = (token);
            return true;
        } catch (JWTVerificationException exception) {
//            throw new RuntimeException("token 无效,请重新获取");
            return false;
        }
    }
}

 Controller

package ;

import ;
import ;
import ;
import ;

@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private JavaJwtUtil javaJwtUtil;

    @RequestMapping("/login")
    public String login() {
        // 验证userName,password和数据库中是否一致,如不一致,直接返回失败
        // 通过userName,password从数据库中获取userId

        String userId = 5 + "";
        String token = (userId);
        ("token:" + token);
        return token;
    }

    //需要token验证
    @RequestMapping("/info")
    public String info() {
        return  "验证通过";
    }
}

测试

访问:http://localhost:8080/auth/login 

前端结果:一串token字符串

访问:http://localhost:8080/auth/info(以token作为header或者参数)

后端结果

: null
	at (:55) ~[main/:na]

解决方案

上边是文章的部分内容,为统一维护,全文已转移到此网址:Spring-解决拦截器中注入Bean失败的问题 - 自学精灵

相关文章