You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring应用登录功能报空指针:userRepository为null,无法调用findAll()

问题解决及优化方案

核心问题:空指针异常原因

你手动通过new UserManager()创建对象,这个对象不在Spring容器的管理范围内,Spring无法自动注入UserRepository,导致调用userRepository.findAll()时触发空指针异常。

修复步骤

1. 将UserManager纳入Spring容器管理

给UserManager添加@Service注解,让Spring负责创建和管理它的实例:

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class UserManager {
    @Autowired
    private UserRepository userRepository;

    public User getUserByID(int id){
        return userRepository.findById(id).get();
    }

    public User getUserByAuthentication(String name, String password){
        Iterable<User> userList = userRepository.findAll();
        ArrayList<User> users = new ArrayList<>();
        userList.forEach(users::add);
        User user = null;
        for (User u : users){
            if (u.getUsername().equals(name) && u.getPassword().equals(password)){
                user = u;
            }
        }
        return user;
    }
}

2. 在Controller中注入UserManager,而非手动实例化

修改Controller代码,通过@Autowired注入UserManager:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

    @Autowired
    private UserManager userManager;

    @PostMapping(path = "/online")
    public ResponseEntity<?> onlineRequest(@RequestBody OnlineRequest onlineRequest) {
        User user = userManager.getUserByAuthentication(onlineRequest.getUsername(), onlineRequest.getPassword());
        if (user != null){
            user.setLatestTimeStamp(System.currentTimeMillis());
            return new ResponseEntity<>("You are now online, Enjoy!", HttpStatus.OK);
        } else {
            return new ResponseEntity<>("Invalid login", HttpStatus.FORBIDDEN);
        }
    }
}

代码优化建议

1. 优化Repository查询逻辑,避免全表扫描

当前查询所有用户再遍历匹配的方式效率极低,在UserRepository中添加自定义查询方法:

import org.springframework.data.repository.CrudRepository;

@Repository
public interface UserRepository extends CrudRepository<User, Integer> {
    User findByUsernameAndPassword(String username, String password);
}

修改UserManager的getUserByAuthentication方法:

public User getUserByAuthentication(String name, String password){
    return userRepository.findByUsernameAndPassword(name, password);
}

2. 密码安全:禁止明文存储

直接存储明文密码是严重安全漏洞,使用BCrypt加密算法哈希存储密码:

  • 注册用户时加密:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// 注册逻辑示例
public User registerUser(String username, String rawPassword) {
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    String encodedPassword = encoder.encode(rawPassword);
    User user = new User();
    user.setUsername(username);
    user.setPassword(encodedPassword);
    return userRepository.save(user);
}
  • 登录时验证:
public User getUserByAuthentication(String name, String rawPassword){
    User user = userRepository.findByUsername(name);
    if (user != null) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (encoder.matches(rawPassword, user.getPassword())) {
            return user;
        }
    }
    return null;
}

同时在Repository中添加对应方法:

User findByUsername(String username);

内容的提问来源于stack exchange,提问作者Alex_X1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:10:27