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
相关产品推荐
相关产品推荐

