本文演示一個極簡的 JavaWeb 登錄/註冊流程,涵蓋:
CREATE DATABASE bookstore CHARSET utf8mb4;
USE bookstore;
CREATE TABLE student (
name VARCHAR(50) PRIMARY KEY,
password VARCHAR(50) NOT NULL
);
INSERT INTO student VALUES ('admin','123456'),('test','abcdef');
cn.edu.hpu
├── model.Student // 實體類,對應表字段
├── dao.DBUtil // 連接工具:載入驅動、獲取連接、關閉資源
├── dao.StudentDAO // 介面:add(), checkLogin()
├── dao.impl.StudentDAOImpl // 實現:PreparedStatement 防注入
├── service.UserService // 介面
├── service.impl.UserServiceImpl // 業務邏輯,調用 DAO
├── servlet.RegisterServlet // 處理註冊 POST
├── servlet.LoginServlet // 處理登錄 POST
└── web/*.jsp // 頁面:register.jsp, login.jsp, success.jsp
public boolean add(Student s) {
String sql = "INSERT INTO student(name,password) VALUES(?,?)";
try (Connection c = DBUtil.getConn(); PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, s.getName()); ps.setString(2, s.getPassword());
return ps.executeUpdate() > 0;
} catch (SQLException e) { throw new RuntimeException(e); }
}
public boolean checkLogin(String name, String pwd) {
String sql = "SELECT 1 FROM student WHERE name=? AND password=?";
try (Connection c = DBUtil.getConn(); PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, name); ps.setString(2, pwd);
return ps.executeQuery().next();
} catch (SQLException e) { throw new RuntimeException(e); }
}
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding("UTF-8");
String name = req.getParameter("username");
String pwd = req.getParameter("password");
boolean ok = new UserServiceImpl().login(name, pwd);
if (ok) {
req.getSession().setAttribute("user", name);
resp.sendRedirect("success.jsp");
} else {
req.setAttribute("msg", "用戶名或密碼錯誤");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
}
<%@ page contentType="text/html;charset=UTF-8" %> 防亂碼。method="post",action 指向 Servlet 路徑。${msg} 顯示錯誤提示。| 問題 | 解決 |
|---|---|
| 中文亂碼 | 全鏈路 UTF-8:DB、連接 URL 加 characterEncoding=utf8、JSP pageEncoding、Servlet req.setCharacterEncoding |
| SQL 注入 | 全程使用 PreparedStatement 佔位符 |
| 資源洩漏 | try-with-resources 自動關閉 Connection/Statement/ResultSet |
| 密碼明文 | 實戰務必用 BCrypt/Argon2 加鹽哈希存儲 |
| 路徑大小寫 | Linux 區分大小寫,包名、文件名、web.xml 映射保持一致 |