SpringBoot应用无法从数据库获取用户数据填充HTML表格问题
问题:SpringBoot应用无法将数据库用户表数据展示到HTML表格
数据库已成功连接,但HTML页面无法获取并填充用户数据。以下是相关代码:
User实体类
package com.example.hardware_inventory.model; public class User { private Long userId; private String username; private String passwordHash; private String role; public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getPasswordHash() { return passwordHash; } public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } // getters and setters }
User Repository类
package com.example.hardware_inventory.repository; import com.example.hardware_inventory.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import org.springframework.dao.EmptyResultDataAccessException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Optional; @Repository public class UserRepository { @Autowired private JdbcTemplate jdbcTemplate; private static final class UserRowMapper implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setUserId(rs.getLong("user_id")); user.setUsername(rs.getString("username")); user.setPasswordHash(rs.getString("password_hash")); user.setRole(rs.getString("role")); return user; } } public List<User> findAll() { String sql = "SELECT * FROM users"; return jdbcTemplate.query(sql, new UserRowMapper()); } public Optional<User> findById(Long id) { String sql = "SELECT * FROM users WHERE user_id = ?"; try { return Optional.ofNullable(jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper())); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } } public Optional<User> findByUsername(String username) { String sql = "SELECT * FROM users WHERE username = ?"; try { return Optional.ofNullable(jdbcTemplate.queryForObject(sql, new Object[]{username}, new UserRowMapper())); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } } public void save(User user) { String sql = "INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, user.getUsername(), user.getPasswordHash(), user.getRole()); } public void update(User user) { String sql = "UPDATE users SET username = ?, password_hash = ?, role = ? WHERE user_id = ?"; jdbcTemplate.update(sql, user.getUsername(), user.getPasswordHash(), user.getRole(), user.getUserId()); } public void deleteById(Long id) { String sql = "DELETE FROM users WHERE user_id = ?"; jdbcTemplate.update(sql, id); } public void resetPassword(Long id, String newPassword) { String sql = "UPDATE users SET password_hash = ? WHERE user_id = ?"; jdbcTemplate.update(sql, newPassword, id); } public void blockUser(Long id) { String sql = "UPDATE users SET role = 'blocked' WHERE user_id = ?"; jdbcTemplate.update(sql, id); } }
User Service类
package com.example.hardware_inventory.service; import com.example.hardware_inventory.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserRepository userRepository; public void resetPassword(Long id, String newPassword) { userRepository.resetPassword(id, newPassword); } public void blockUser(Long id) { userRepository.blockUser(id); } }
前端HTML页面(add_new_user.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Add New User</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="form-container"> <h1>Add New User</h1> <form id="add-user-form"> <input type="text" id="new-username" placeholder="Username" required> <input type="password" id="new-password" placeholder="Password" required> <select id="role"> <option value="user">User</option> <option value="admin">Admin</option> </select> <button type="submit">Add User</button> </form> </div> <div class="table-container"> <h1>All Users</h1> <table id="users-table"> <thead> <tr> <th>User ID</th> <th>Username</th> <th>Role</th> <th>Actions</th> </tr> </thead> <tbody> <!-- Dynamic rows will be inserted here --> </tbody> </table> </div> <script src="scripts.js"></script> </body> </html>
前端JavaScript代码(scripts.js)
document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('add-user-form'); const usersTable = document.getElementById('users-table').getElementsByTagName('tbody')[0]; // Fetch users and display them fetch('/api/users') .then(response => response.json()) .then(data => { data.forEach(user => { addUserRow(user); }); }); // Handle form submission form.addEventListener('submit', function(event) { event.preventDefault(); const newUsername = document.getElementById('new-username').value; const newPassword = document.getElementById('new-password').value; const role = document.getElementById('role').value; fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: newUsername, password: newPassword, role: role }) }) .then(response => response.json()) .then(user => { addUserRow(user); form.reset(); }); }); function addUserRow(user) { const row = usersTable.insertRow(); const cellId = row.insertCell(0); const cellUsername = row.insertCell(1); const cellRole = row.insertCell(2); const cellActions = row.insertCell(3); cellId.textContent = user.userId; cellUsername.textContent = user.username; cellRole.textContent = user.role; cellActions.innerHTML = `<form action="/api/users/delete/${user.userId}" method="post"> <button type="submit">Delete</button> </form>`; } });
排查和修复步骤
添加缺失的REST控制器(核心问题)
前端发起的/api/users请求没有对应的后端接口处理,这是无法获取数据的关键原因。添加如下Controller:package com.example.hardware_inventory.controller; import com.example.hardware_inventory.model.User; import com.example.hardware_inventory.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; // 获取所有用户 @GetMapping public List<User> getAllUsers() { return userService.getAllUsers(); } // 添加新用户 @PostMapping public ResponseEntity<User> createUser(@RequestBody User user) { // 实际项目需加密密码,此处仅示例 userService.saveUser(user); // 需修改UserService添加saveUser方法,或直接调用Repository return ResponseEntity.status(HttpStatus.CREATED).body(user); } // 删除用户 @PostMapping("/delete/{id}") public ResponseEntity<Void> deleteUser(@PathVariable Long id) { userService.deleteUser(id); return ResponseEntity.ok().build(); } // 补充重置密码、封禁用户接口 @PostMapping("/reset-password/{id}") public ResponseEntity<Void> resetPassword(@PathVariable Long id, @RequestParam String newPassword) { userService.resetPassword(id, newPassword); return ResponseEntity.ok().build(); } @PostMapping("/block/{id}") public ResponseEntity<Void> blockUser(@PathVariable Long id) { userService.blockUser(id); return ResponseEntity.ok().build(); } }完善UserService的查询与保存方法
当前Service缺少获取所有用户和保存用户的方法,补充如下:@Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getAllUsers() { return userRepository.findAll(); } public void saveUser(User user) { userRepository.save(user); } public void deleteUser(Long id) { userRepository.deleteById(id); } // 已有方法... }修复前后端字段不匹配问题
前端POST请求发送的是password,但实体类对应字段是passwordHash,修改JS请求体:body: JSON.stringify({ username: newUsername, passwordHash: newPassword, // 与实体类字段名统一 role: role })添加前端错误调试
为fetch请求添加错误捕获,便于定位问题:fetch('/api/users') .then(response => { if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`); return response.json(); }) .then(data => { data.forEach(user => addUserRow(user)); }) .catch(error => console.error('获取用户列表失败:', error));密码存储安全优化
不要存储明文密码,使用BCrypt加密:// 在配置类中声明加密Bean @Configuration public class SecurityConfig { @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } } // 在保存用户时加密 @Autowired private BCryptPasswordEncoder passwordEncoder; public void saveUser(User user) { user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash())); userRepository.save(user); }
内容的提问来源于stack exchange,提问作者N P Singh
相关产品推荐
相关产品推荐

