JavaWeb开发 : tomcat+Servlet+JSP-Mysql

时间:2024-11-28 11:49:43

先创建数据库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);
    }
}