// 在 Java 代碼中拼接 HTML - 維護噩夢
out.println("");
out.println("用戶列表
");
out.println("缺點:視圖邏輯與業務邏輯耦合,前後端協作困難,修改頁面需重新編譯 Java 類。
<%-- 頁面中混雜大量 Java 邏輯 --%>
<%
List<User> users = userDao.findAll();
for (User u : users) {
%>
<tr><td><%= u.getName() %></td></tr>
<% } %>
缺點:JSP 變成「大雜燴」,職責不清,難以複用與測試。
將數據封裝為 JavaBean,JSP 僅負責顯示。但控制邏輯(請求分發、參數處理)仍分散在各 JSP 中。
這是經典的 MVC Model 2 架構,也是後續 Struts、Spring MVC 等框架的基石。
┌─────────────────────────────────────┐ │ Presentation Layer │ ← JSP / Thymeleaf / Vue/React │ (Controller: Servlet / @Controller)│ ├─────────────────────────────────────┤ │ Service Layer │ ← @Service 業務邏輯、事務控制 │ (Business Logic & Transaction) │ ├─────────────────────────────────────┤ │ DAO Layer │ ← @Repository / Mapper 數據訪問 │ (CRUD & ORM: MyBatis/JPA) │ ├─────────────────────────────────────┤ │ Database │ └─────────────────────────────────────┘
| 層級 | 核心職責 | 關鍵規範 | 典型技術 |
|---|---|---|---|
| Controller | 請求接收、參數校驗、調用 Service、視圖跳轉/JSON 返回 | 不含業務邏輯、不直接操作 DB、薄控制器 | Spring MVC @RestController |
| Service | 核心業務流程、事務管理(@Transactional)、異常處理、聚合多 DAO | 接口隔離實現、領域模型驅動、無視圖依賴 | Spring @Service + @Transactional |
| DAO/Mapper | 單表/多表 CRUD、複雜查詢、結果映射 | 面向接口編程、SQL 與代碼分離、無業務邏輯 | MyBatis Mapper / Spring Data JPA |
| Entity/DTO/VO | 數據載體:Entity 對應表、DTO 服務層傳輸、VO 視圖層展示 | Getter/Setter、無參構造、序列化、校驗註解 | Lombok @Data / Record (Java 16+) |
Serializable 接口private 封裝getXxx/setXxx 方法(布爾型可用 isXxx)// Service 接口
public interface UserService {
UserDTO getById(Long id);
PageResult<UserDTO> query(UserQuery query);
}
// Controller 僅依賴接口
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService; // 構造器注入
@GetMapping("/{id}")
public Result<UserDTO> get(@PathVariable Long id) {
return Result.success(userService.getById(id));
}
}
MapStruct 或手動轉換器避免層間對象污染@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BizException.class)
public Result<Void> handleBiz(BizException e) {
return Result.fail(e.getCode(), e.getMessage());
}
}
Controller、DAO 層 禁止 使用 @Transactional。事務應圍繞完整業務用例,而非單條 SQL。
MVC 與三層架構不僅是代碼組織形式,更是關注點分離的工程實踐。從早期的 Servlet/JSP 到現代 Spring Boot + 前後端分離,核心思想始終未變:控制器調度、服務封裝業務、數據層專注持久化。遵循分層規範、接口隔離、對象分離,才能構建可維護、可測試、可擴展的企業級應用。