@Autowired注入JwtService出现NullPointerException问题求助
问题:@Autowired注入JwtService时出现NullPointerException
我在使用@Autowired注入JwtService到JwtTokenValidator过滤器时,遇到了NullPointerException,错误提示this.jwtService为null。已确认JwtService带有@Service注解,是Spring管理的Bean,且没有手动实例化它。
JwtTokenValidator代码
@Component @AllArgsConstructor @NoArgsConstructor public class JwtTokenValidator extends OncePerRequestFilter { @Autowired private JwtService jwtService; @Override protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { final String authHeader = request.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { filterChain.doFilter(request, response); return; } String token = authHeader.substring(7); try { String email = jwtService.extractEmail(token); String authorities = jwtService.extractAuthorities(token); List<GrantedAuthority> auth = AuthorityUtils.commaSeparatedStringToAuthorityList(authorities); Authentication authentication = new UsernamePasswordAuthenticationToken(email, null, auth); SecurityContextHolder.getContext().setAuthentication(authentication); filterChain.doFilter(request, response); } catch (Exception e) { SecurityContextHolder.clearContext(); throw e; } } }
JwtService代码
@Service public class JwtService { private SecretKey key = Keys.hmacShaKeyFor(JwtConstant.SECRET_KEY.getBytes()); public String extractEmail(String token) { return String.valueOf(extractAllClaims(token).get("email")); } public String extractAuthorities(String token) { return String.valueOf(extractAllClaims(token).get("authorities")); } public Claims extractAllClaims(String token){ return Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); } public String generateToken(Authentication authentication){ Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); String roles = populateAuthorities(authorities); return Jwts.builder() .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 24))) .claim("email", authentication.getName()) .claim("authorities", roles) .signWith(key, SignatureAlgorithm.HS256) .compact(); } public String populateAuthorities(Collection <? extends GrantedAuthority> authorities){ Set<String> auths = new HashSet<>(); for(GrantedAuthority authority : authorities){ auths.add(authority.getAuthority()); } return String.join(",",auths); } }
错误信息
java.lang.NullPointerException: Cannot invoke "com.Abdelouadoud.MoroccoCraftsAPI.config.JwtService.extractEmail(String)" because "this.jwtService" is null at com.Abdelouadoud.MoroccoCraftsAPI.config.JwtTokenValidator.doFilterInternal(JwtTokenValidator.java:55) ~[classes/:na]
解决方法
1. 修正注入方式,移除冲突注解
同时使用@AllArgsConstructor、@NoArgsConstructor和@Autowired会导致Spring可能通过无参构造器创建实例,进而无法注入JwtService。建议改用构造器注入(Spring推荐方式):
修改JwtTokenValidator:
@Component @AllArgsConstructor public class JwtTokenValidator extends OncePerRequestFilter { // 移除@Autowired,改为private final字段,通过@AllArgsConstructor生成的构造器注入 private final JwtService jwtService; // doFilterInternal方法保持不变 }
2. 检查过滤器的注册方式
如果在Security配置中手动注册过滤器,禁止直接new实例,必须从Spring容器获取Bean:
错误写法:
// 错误:手动new的实例不受Spring管理,无法注入依赖 http.addFilterBefore(new JwtTokenValidator(), UsernamePasswordAuthenticationFilter.class);
正确写法:
@Configuration @EnableWebSecurity @AllArgsConstructor public class SecurityConfig { // 从Spring容器注入过滤器实例 private final JwtTokenValidator jwtTokenValidator; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.addFilterBefore(jwtTokenValidator, UsernamePasswordAuthenticationFilter.class); // 其他安全配置 return http.build(); } }
3. 确认组件扫描范围
确保JwtTokenValidator和JwtService所在的包被Spring扫描到:
- 主启动类所在包是两个类的父包(Spring默认扫描主启动类所在包及子包)
- 或者在主启动类上添加
@ComponentScan(basePackages = "com.Abdelouadoud.MoroccoCraftsAPI")指定扫描范围
内容的提问来源于stack exchange,提问作者abdelouadoud laadimi
相关产品推荐
相关产品推荐

