调用Spring数据JPA存储库时出现NullPointerException

调用Spring数据JPA存储库时出现NullPointerException,spring,spring-security,spring-data-jpa,spring-data,Spring,Spring Security,Spring Data Jpa,Spring Data,当我调用API来验证前端的令牌时,我在调用UserDetails服务的loadUserByUsername方法时遇到了问题。我可以将用户名传递给该方法,但我的userRepository无法执行findByUsername方法,我不确定发生了什么。我在调用之前打印出名称,它返回正确的用户名,数据库中也存在该名称的用户 这是我在控制台中得到的: 2020-07-09 22:46:55.121 INFO 18048 --- [nio-8080-exec-4] o.s.web.servlet.Dis

当我调用API来验证前端的令牌时,我在调用UserDetails服务的
loadUserByUsername
方法时遇到了问题。我可以将用户名传递给该方法,但我的
userRepository
无法执行
findByUsername
方法,我不确定发生了什么。我在调用之前打印出名称,它返回正确的用户名,数据库中也存在该名称的用户

这是我在控制台中得到的:

2020-07-09 22:46:55.121  INFO 18048 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Completed initialization in 10 ms
2020-07-09 22:46:55.153  INFO 18048 --- [nio-8080-exec-4] c.g.Apollo.security.jwt.JwtFilter        : token not presented...
2020-07-09 22:46:55.759  INFO 18048 --- [nio-8080-exec-4] c.g.Apollo.service.UserService           : success...
2020-07-09 22:47:10.885  INFO 18048 --- [nio-8080-exec-5] c.g.Apollo.security.jwt.JwtFilter        : token not presented...
2020-07-09 22:47:10.898  INFO 18048 --- [nio-8080-exec-5] c.g.A.s.jwt.JwtUserDetailsService        : load user... max123
2020-07-09 22:47:10.909  WARN 18048 --- [nio-8080-exec-5] g.e.SimpleDataFetcherExceptionHandler    : Exception while fetching data (/verifyToken) : null

java.lang.NullPointerException: null
    at com.**.Apollo.security.jwt.JwtUserDetailsService.loadUserByUsername(JwtUserDetailsService.java:23) ~[classes/:na]
    at com.**.Apollo.service.UserService.verifyToken(UserService.java:173) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at io.leangen.graphql.metadata.execution.SingletonMethodInvoker.execute(SingletonMethodInvoker.java:21) ~[spqr-0.9.9.jar:na]
当我登录用户时,UserRepository方法工作正常,但在这里失败

JwtUserDetailsService,这是从verifyToken方法调用的:

@Slf4j
@Service
public class JwtUserDetailsService implements UserDetailsService {

private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) {
    log.info("load user... {}", username);
    Optional<User> user = userRepository.findByUsername(username);
    log.info("after");
    if (user.isPresent()) {
        log.info("user:: {}", user.get().getUsername());
        return getJwtUser(user.get());
    } else {
        log.info("user not found");
        return null;
    }
}

public JwtUser getJwtUser(User user) {
    return new JwtUser(
            user.getId(),
            user.getUsername(),
            user.getFirstName(),
            user.getLastName(),
            user.getEmail(),
            user.getPassword(),
            List.of(new SimpleGrantedAuthority(user.getRole().getRoleName().name())),
            user.getEnabled(),
            null
    );
}
@Slf4j
@服务
公共类JwtUserDetailsService实现UserDetailsService{
私有用户存储库用户存储库;
@凌驾
公共用户详细信息loadUserByUsername(字符串用户名){
log.info(“加载用户…{}”,用户名);
可选用户=userRepository.findByUsername(用户名);
日志信息(“之后”);
if(user.isPresent()){
log.info(“user::{}”,user.get().getUsername());
返回getJwtUser(user.get());
}否则{
log.info(“未找到用户”);
返回null;
}
}
公共JwtUser getJwtUser(用户用户){
返回新JwtUser(
user.getId(),
user.getUsername(),
user.getFirstName(),
user.getLastName(),
user.getEmail(),
user.getPassword(),
列表(新的SimpleGrantedAuthority(user.getRole().getRoleName().name()),
user.getEnabled(),
无效的
);
}
用户存储库:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findByUsername(String username);

    boolean existsByUsername(String username);

    Optional<User> findByToken(String token);
}
@存储库
公共接口用户存储库扩展了JpaRepository{
可选findByUsername(字符串用户名);
布尔existsByUsername(字符串用户名);
可选findByToken(字符串标记);
}
UserSerice,这是向前端公开的内容:

@GraphQLQuery
public User verifyToken(String token) {
    Optional<User> optionalUser = userRepository.findByToken(token);
    if(optionalUser.isPresent()) {
        UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(optionalUser.get().getUsername());
        if(jwtTokenUtil.isTokenValid(token, userDetails)) {
            return optionalUser.get();
        }
    }
    return null;
}
@GraphQLQuery
公共用户验证令牌(字符串令牌){
可选选项user=userRepository.findByToken(令牌);
if(optionalUser.isPresent()){
UserDetails UserDetails=jwtUserDetailsService.loadUserByUsername(optionalUser.get().getUsername());
if(jwtTokenUtil.isTokenValid(令牌,用户详细信息)){
返回optionalUser.get();
}
}
返回null;
}

它正在抛出一个
NullPointerException
,因为
JwtUserDetailsService
中的
userRepository
未被注入,而是
null

创建一个构造函数,如下所示:

public JwtUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
}

它正在抛出一个
NullPointerException
,因为
JwtUserDetailsService
中的
userRepository
未被注入,并且是
null

创建一个构造函数,如下所示:

public JwtUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
}

您需要在JwtUserDetailsService类中添加
@Autowired

@Autowired
private UserRepository userRepository;

您需要在JwtUserDetailsService类中添加
@Autowired

@Autowired
private UserRepository userRepository;

您的
UserRepository
依赖项似乎没有被注入到
jwtuserdetails服务中,因为您没有自动连接它

您可以执行以下操作:

public JwtUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
}
使用构造函数注入自动关联依赖项,这是推荐的方法:

private final UserRepository userRepository;

public JwtUserDetailsService(UserRepository userRepository)  {
    this.userRepository = userRepository;
} 
不建议自动连接您的私人成员

由于您已经在使用ProjectLombok,更优雅的方法是使用
@RequiredArgsConstructor
注释类,而不是编写构造函数

   @Slf4j
   @RequiredArgsConstructor
   @Service
   public class JwtUserDetailsService implements UserDetailsService {

     private final UserRepository userRepository; 
     ..

   }

在这里,lombok项目将为您生成一个构造函数,该构造函数将负责依赖项注入。

您的
用户存储库
依赖项似乎没有被注入
JWTUserDetails服务
,因为您没有自动连接它

您可以执行以下操作:

public JwtUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
}
使用构造函数注入自动关联依赖项,这是推荐的方法:

private final UserRepository userRepository;

public JwtUserDetailsService(UserRepository userRepository)  {
    this.userRepository = userRepository;
} 
不建议自动连接您的私人成员

由于您已经在使用ProjectLombok,更优雅的方法是使用
@RequiredArgsConstructor
注释类,而不是编写构造函数

   @Slf4j
   @RequiredArgsConstructor
   @Service
   public class JwtUserDetailsService implements UserDetailsService {

     private final UserRepository userRepository; 
     ..

   }

在这里,lombok项目将为您生成一个构造函数,该构造函数将负责依赖项注入。

感谢您的响应,这是我最终做的,而不是添加构造函数。感谢您的响应,这是我最终做的,而不是添加构造函数。