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; // 直接輸出響應,不跳轉視圖
}
}
定義一個領域對象屬性(如 `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" />
實現 `ModelDriven
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;
}
}
| 維度 | 基本屬性驅動 | 領域模型驅動 | ModelDriven |
|---|---|---|---|
| 代碼量 | 少(簡單場景) | 中 | 中 |
| 參數封裝 | 手動封裝到模型 | 自動封裝到模型 | 自動封裝到模型 |
| 前端字段名 | userName | user.userName | userName |
| 驗證支援 | 需手動驗證 | 支援模型級驗證 | 支援模型級驗證 |
| 適用場景 | 參數極少、無模型、Ajax 簡單交互 | 標準 CRUD、表單提交、複雜業務 | 單模型 CRUD、RESTful API、參數名需保持簡潔 |
| 多模型支援 | 易擴展 | 易擴展 (user, order 等) | 僅單一模型 |
掌握這三種方式的本質差異,能讓你在面對不同業務複雜度時,選擇最恰當的參數處理策略,編寫出既符合框架慣例又易於維護的 Action 代碼。