先创建数据库javaweb
连接数据库
package db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Database {
private static final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=UTF-8";
private static final String USER = "root";
private static final String PASSWORD = "root";
public static Connection getConnection() throws SQLException {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("Database connected");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
DAO
DAO(Data Access Object) 是一种常用的设计模式,旨在将应用程序的业务逻辑与数据访问逻辑分离,从而提高代码的可维护性、可扩展性和测试性。
使用model层,将sql语句封装,提供接口给servlet
package db;
import model.User;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;
public class UserDAO {
// 检查用户名是否已存在
public boolean isUsernameExists(String username) {
String sql = "SELECT COUNT(*) FROM users WHERE username = ?";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return rs.getInt(1) > 0;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
// 注册用户
public boolean registerUser(String username, String password) {
if (isUsernameExists(username)) {
System.out.println("username already exists!");
return false;
}
// 生成盐并加密密码
String salt = generateSalt();
String encryptedPassword = encryptPassword(password, salt);
String sql = "INSERT INTO users (username, password, salt) VALUES (?, ?, ?)";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
stmt.setString(2, encryptedPassword); // 只存储加密后的密码
stmt.setString(3, salt); // 单独存储盐
int rowsInserted = stmt.executeUpdate();
return rowsInserted > 0;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
// 用户登录
public User loginUser(String username, String password) {
String sql = "SELECT user_id, password, salt FROM users WHERE username = ?";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
int userId = rs.getInt("user_id");
String storedEncryptedPassword = rs.getString("password");
String salt = rs.getString("salt");
if (storedEncryptedPassword.equals(encryptPassword(password, salt))) {
System.out.println("login success!");
// 返回一个 User 对象,包含用户ID、用户名、盐和密码
return new User(userId, username, storedEncryptedPassword, salt);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("username or password incorrect!");
return null; // 登录失败返回 null
}
// 加密密码
private String encryptPassword(String password, String salt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt.getBytes()); // 使用盐加密密码
byte[] hashedPassword = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(hashedPassword);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 生成盐
private String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
}