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

Struts2 Action 接收參數的三種核心方式深度解析

     編輯:Java 綜合教學

Struts2 參數接收機制概覽

Struts2 通過攔截器自動將請求參數映射到 Action 屬性或模型對象中。理解三種核心方式的原理與適用場景,能寫出更清晰、可維護的代碼。本文以「用戶名註冊查重」為例,逐一剖析。

方式一:基本屬性驅動 —— 最直觀、適合簡單參數

在 Action 中定義與表單字段同名的屬性及其 Getter/Setter,Params 攔截器自動注入。

public class CheckUserAction extends ActionSupport {
    private String userName;  // 對應表單 name="userName"

    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }

    @Override
    public String execute() throws Exception {
        User user = new User();
        user.setUserName(this.userName);  // 手動封裝到模型
        UserDAO dao = new UserDAO();
        HttpServletResponse response = ServletActionContext.getResponse();
        PrintWriter out = response.getWriter();
        out.print(dao.checkExists(user) ? "1" : "0");
        return NONE;  // 直接輸出響應,不跳轉視圖
    }
}
  • 優點: 簡單直接,無需額外模型類,適合 1-3 個參數的簡單場景。
  • 缺點: 參數多時 Action 膨脹,業務邏輯與參數處理耦合,難以復用驗證邏輯。
  • 前端無需變動: 表單字段名直接對應屬性名。

方式二:領域模型驅動 —— 企業級開發主流選擇

定義一個領域對象屬性(如 `private User user;`),表單字段命名為 `user.userName`、`user.password`,Params 攔截器自動調用 `getUser().setUserName(...)` 完成巢狀賦值。

public class CheckUserAction extends ActionSupport {
    private User user = new User();  // 必須預先實例化

    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }

    @Override
    public String execute() throws Exception {
        UserDAO dao = new UserDAO();
        HttpServletResponse response = ServletActionContext.getResponse();
        PrintWriter out = response.getWriter();
        out.print(dao.checkExists(user) ? "1" : "0");
        return NONE;
    }
}

前端表單調整:

<input type="text" name="user.userName" />
<input type="password" name="user.password" />
  • 優點: 參數自動封裝到領域對象,Action 代碼乾淨,便於驗證(Validate 攔截器支援模型驗證)、復用、單元測試。
  • 缺點: 前端字段名變長,需注意模型對象必須預先實例化避免空指針。
  • 最佳實踐: 結合 `ModelDriven` 介面可進一步簡化(見方式三)。

方式三:ModelDriven 介面 —— 模型驅動的極致封裝

實現 `ModelDriven` 介面,將模型對象作為 Action 的「根對象」,參數直接映射到模型屬性(表單字段名仍為 `userName`),Action 通過 `getModel()` 獲取模型實例。

public class CheckUserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();  // 3. 定義並初始化模型

    @Override
    public User getModel() {  // 2. 實現介面方法
        return user;
    }

    // 1. 可選:提供 getter/setter 供其他攔截器或 JSP 訪問
    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }

    @Override
    public String execute() throws Exception {
        UserDAO dao = new UserDAO();
        HttpServletResponse response = ServletActionContext.getResponse();
        PrintWriter out = response.getWriter();
        out.print(dao.checkExists(user) ? "1" : "0");  // 直接使用 user
        return NONE;
    }
}
  • 核心流程:
    1. Action 實現 `ModelDriven`
    2. 實現 `getModel()` 返回模型實例
    3. 模型預先實例化 (`new User()`)
    4. 可選:提供 getter/setter
  • 前端無需變動: 表單字段名仍為 `userName`,Params 攔截器識別 `ModelDriven` 類型時,直接對模型對象賦值。
  • 優點: 參數名簡潔、Action 直接操作模型、支援鏈式調用。
  • 缺點: 僅支援單一模型對象,多模型場景受限;模型屬性名衝突時難以區分。

三種方式對比與選型指南

維度基本屬性驅動領域模型驅動ModelDriven
代碼量少(簡單場景)中中
參數封裝手動封裝到模型自動封裝到模型自動封裝到模型
前端字段名userNameuser.userNameuserName
驗證支援需手動驗證支援模型級驗證支援模型級驗證
適用場景參數極少、無模型、Ajax 簡單交互標準 CRUD、表單提交、複雜業務單模型 CRUD、RESTful API、參數名需保持簡潔
多模型支援易擴展易擴展 (user, order 等)僅單一模型

進階建議

  1. 統一規範: 團隊內統一採用「領域模型驅動」作為預設模式,特定場景(如 Ajax 校驗)使用基本屬性或 ModelDriven。
  2. 模型預初始化: 无论哪種方式,模型對象(User、Dept 等)務必在聲明處或構造器中 `new`,避免空指針。
  3. 類型轉換: 複雜類型(日期、枚舉、自定義類)需註冊 `TypeConverter`,Struts2 默認僅處理基本類型與字符串。
  4. 安全防範: 開啟 `struts.action.excludeParams` 過濾敏感屬性(如 `password`、`id`),防止惡意綁定。

掌握這三種方式的本質差異,能讓你在面對不同業務複雜度時,選擇最恰當的參數處理策略,編寫出既符合框架慣例又易於維護的 Action 代碼。

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