本文通過一個完整的用戶註冊/登錄模塊,展示經典的「Servlet + Service + DAO」三層架構落地,涵蓋單元測試、業務異常處理、JSP EL 表達式判斷登錄狀態、Servlet 控制器邏輯等核心環節。
XmlUserDao(基於 XML 檔案存儲)UserService(業務邏輯、異常拋出)LoginServlet(請求處理、Session 管理)+ JSP 頁面xmlUserDaoTest(JUnit 驗證 DAO 功能)package com.tsh.test;
import org.junit.Test;
import com.tsh.dao.XmlUserDao;
import com.tsh.domain.User;
public class xmlUserDaoTest {
@Test
public void testFindUserByUsername() {
XmlUserDao dao = new XmlUserDao();
User user = dao.findUserByUsername("taoshihan");
System.out.println(user);
}
@Test
public void testAddUser() {
XmlUserDao dao = new XmlUserDao();
User user = new User();
user.setUsername("taoshihan");
user.setPassword("123456");
dao.addUser(user);
}
}
要點:直接實例化 DAO 測試,驗證查詢與新增功能,無需啟動容器。
package com.tsh.service;
import com.tsh.dao.XmlUserDao;
import com.tsh.domain.User;
import com.tsh.exception.MsgException;
public class UserService {
public void registerUser(User user) throws MsgException {
XmlUserDao dao = new XmlUserDao();
// 業務規則:用戶名唯一性檢查
if (dao.findUserByUsername(user.getUsername()) != null) {
throw new MsgException("用戶名已經存在");
}
dao.addUser(user);
}
}
設計亮點:
MsgException 承載業務錯誤訊息,避免使用通用異常<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>用戶中心</title>
</head>
<body>
<h1>用戶中心</h1>
<hr>
<c:if test="${sessionScope.user == null}">
歡迎光臨,遊客!
<a href="${pageContext.request.contextPath}/login.jsp">登錄</a>
<a href="${pageContext.request.contextPath}/register.jsp">註冊</a>
</c:if>
<c:if test="${sessionScope.user != null}">
歡迎光臨,${sessionScope.user.username}!
<a href="${pageContext.request.contextPath}/Servlet/logout">註銷</a>
</c:if>
</body>
</html>
核心技術:
<c:if> 條件渲染sessionScope 獲取 Session 屬性pageContext.request.contextPath 動態生成項目路徑,避免硬編碼package com.tsh.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tsh.dao.XmlUserDao;
import com.tsh.domain.User;
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
// 參數校驗
if ("".equals(username) || password == null || "".equals(password)) {
request.setAttribute("msg", "用戶名和密碼不能為空!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
XmlUserDao dao = new XmlUserDao();
User user = dao.findUserByUsername(username);
if (user != null && user.getPassword().equals(password)) {
request.getSession().setAttribute("user", user);
response.getWriter().write("登錄成功!");
} else {
response.getWriter().write("用戶名或密碼錯誤");
}
}
}
關鍵點:
null 判斷| 現狀 | 改進方向 |
|---|---|
| Servlet 直接 new DAO | 引入 Spring IOC,注入 Service |
| 密碼明文比對 | BCrypt 加密存儲,驗證時比對雜湊值 |
| XML 檔案存儲 | 遷移至 MySQL + MyBatis/JPA |
| 手動參數獲取 | 使用 Spring MVC @RequestParam 自動綁定 |
| 硬編碼跳轉路徑 | 統一視圖解析器,邏輯視圖名 |
這個簡單案例完整演示了三層架構的分工協作,是理解 Java EE 基礎開發模式的優秀入門範例。