首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

在 JSP/Servlet 開發中導入事件驅動架構:MVC 模式下的訊息分派機制

     編輯:J2EE

背景痛點:傳統 JSP/Servlet 開發現狀

  • 代碼重用率低,大量重複的 if-else 判斷請求類型。
  • 業務邏輯散落在 JSP/Servlet 中,難以單元測試。
  • 無法應對大型複雜 Web 應用的擴展需求。

解決之道:MVC + 事件驅動,將「請求處理」轉化為「事件分派」。

MVC 分層映射

層職責技術實現
Model (模型)業務邏輯、資料存取、領域模型純 Java 類 (POJO/JavaBean/EJB)
View (視圖)使用者介面渲染、表單呈現JSP / 模板引擎
Controller (控制器)接收事件、協調模型、選擇視圖Servlet (核心分派器)

視圖與模型的抽象解耦

同一邏輯抽象可對應多種視圖表現:

  • SingleSelection 抽象 → Radio Button / 下拉選單 / List Box
  • Submission 抽象 → Submit Button / 超連結 / 圖片 / JS form.submit()

Controller 不關心具體 UI 元素,只處理語義事件。

Servlet 事件驅動核心機制

1. 統一入口:重寫 service()/doGet()/doPost()

public class EventDrivenServlet extends HttpServlet {
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 統一委派給 act 方法
        act(req, resp);
    }
    
    protected void act(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 核心分派邏輯
    }
}

2. 訊息物件體系:語義化請求意圖

// 基礎訊息
public abstract class Message {}

// 具體訊息
public class LoginMessage extends Message {
    private Map credentials = new HashMap<>();
    public void setCredential(String key, String val) { credentials.put(key, val); }
    public String getCredential(String key) { return credentials.get(key); }
}

public class ChangePasswordMessage extends Message {
    private Map credentials = new HashMap<>();
    // ... 同樣結構
}

每個可提交的 UI 元素對應一個 Submission,產生特定 Message 子類實例,攜帶表單資料。

3. 核心分派演算法

protected void act(HttpServletRequest req, HttpServletResponse resp, Message msg)
        throws ServletException, IOException {
    // 1. 解析請求 → 建立 Message(此處簡化,實際由前端/攔截器建構)
    Message message = buildMessageFromRequest(req);
    
    // 2. 根據訊息類型分派
    if (message instanceof LoginMessage) {
        handleLogin((LoginMessage) message, req, resp);
    } else if (message instanceof ChangePasswordMessage) {
        handleChangePassword((ChangePasswordMessage) message, req, resp);
    } else {
        // 未知訊息處理
    }
}

void handleLogin(LoginMessage msg, HttpServletRequest req, HttpServletResponse resp) {
    String username = msg.getCredential("username");
    String password = msg.getCredential("password");
    
    // 調用 Model 層業務邏輯
    UserService service = ServiceFactory.getUserService();
    User user = service.authenticate(username, password);
    
    // 3. 結果反映至回應
    if (user != null) {
        req.getSession().setAttribute("user", user);
        forwardToPage(req, resp, "/dashboard.jsp");
    } else {
        req.setAttribute("error", "帳號或密碼錯誤");
        forwardToPage(req, resp, "/login.jsp");
    }
}

4. act 方法標準化六步驟

  1. 解析 Request → 建立/更新領域物件。
  2. 初始化/更新 Model → 注入請求資料。
  3. 調用業務邏輯 → Service 層處理。
  4. 結果寫入 Response/Session/Request → 供 View 讀取。
  5. 決定下一視圖 → 根據業務結果選擇 JSP。
  6. Forward/Redirect → 完成流程。

前端與訊息建構整合

JSP 表單隱藏訊息類型

<form action="EventDrivenServlet" method="post">
    <input type="hidden" name="messageType" value="LoginMessage" />
    帳號:<input name="username" /><br/>
    密碼:<input type="password" name="password" /><br/>
    <input type="submit" value="登入" />
</form>

Servlet 解析建構 Message

private Message buildMessageFromRequest(HttpServletRequest req) {
    String type = req.getParameter("messageType");
    try {
        Class clazz = Class.forName("com.example.msg." + type);
        Message msg = (Message) clazz.newInstance();
        // 將所有參數注入 Message Map
        Enumeration names = req.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (!"messageType".equals(name)) {
                msg.setCredential(name, req.getParameter(name));
            }
        }
        return msg;
    } catch (Exception e) {
        throw new ServletException("無法建構訊息: " + type, e);
    }
}

架構優勢總結

傳統模式事件驅動模式
Servlet 中大量 if-else 判斷 action 參數多型分派,新增功能只需新增 Message 類與 Handler
業務邏輯耦合在 ServletModel 純粹化,可獨立單元測試
參數手工獲取、轉換Message 封裝參數映射,自動化程度高
難以擴展新業務流程開放封閉原則:擴展不修改核心分派器

演進方向:現代框架的雛形

  • Struts 1:ActionForm + Action 即此模式具體化。
  • Spring MVC:@Controller + @RequestMapping + @ModelAttribute 註解化分派。
  • 前端控制器模式:單一 Servlet 統一入口,攔截器鏈預處理,HandlerMapping 分派。

總結

在 JSP/Servlet 基礎上導入事件驅動,核心在於將 HTTP 請求語義化為 Message 物件,以多型分派替代條件判斷,實現 Controller 與 Model 的解耦。此模式是現代 MVC 框架的架構雛形,理解其原理有助於深度掌握框架運作機制,亦可在無法引入框架的輕量專案中直接應用,顯著提升代碼結構品質。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved