Struts 2 透過 OGNL 實現請求參數向 Action 屬性的自動綁定,支援三種截然不同的模式,各有適用場景與優缺點。
原理:Action 直接定義屬性(含 Getter/Setter),參數名與屬性名一一對應。
// JSP
<form action="sys/login.action" method="post">
<input type="text" name="username">
<input type="submit" value="submit">
</form>
// Action
public class SysAction extends ActionSupport {
private String username; // + getter/setter
public String login() {
System.out.println(username); // 直接使用
return SUCCESS;
}
}
優點:簡單直接、無額外介面、適合少量參數。
缺點:參數多時 Action 膨脹、屬性分散、難以複用驗證邏輯。
原理:Action 實作 ModelDriven<T>,提供 getModel() 返回模型實例(必須 new),參數綁定至模型屬性。
// JSP 同上,name="username"
// Action
public class SysAction extends ActionSupport implements ModelDriven<User> {
private User user; // 必須初始化
public User getModel() {
if (user == null) user = new User();
return user;
}
public String login() {
System.out.println(getModel().getUsername());
return SUCCESS;
}
}
優點:模型封裝性好、可複用於多 Action、支援驗證註解(@Validations)。
缺點:單 Action 僅支援一個模型,多模型場景無力。
原理:Action 定義多個模型屬性(無需實作介面、無需 new),參數名加前綴 模型屬性名.屬性,Struts 2 自動實例化並設值(需提供 Setter)。
// JSP
<form action="sys/login.action" method="post">
<input type="text" name="user.username">
<input type="text" name="teacher.level">
<input type="submit" value="submit">
</form>
// Action
public class SysAction extends ActionSupport {
private User user;
private Teacher teacher; // + setter (無需 getter、無需 new)
public String login() {
System.out.println(user.getUsername());
System.out.println(teacher.getLevel());
return SUCCESS;
}
public void setUser(User user) { this.user = user; }
public void setTeacher(Teacher teacher) { this.teacher = teacher; }
}
優點:單 Action 支援任意多模型、參數命名空間隔離、無介面侵入。
缺點:前端參數名較長、Action 需為每個模型寫 Setter。
| 場景 | 推薦模式 | 理由 |
|---|---|---|
| 簡單 CRUD、參數 < 5 | 屬性驅動 | 零樣板、直觀 |
| 單一核心模型、需驗證復用 | 模型驅動 | 封裝性佳、配合驗證框架 |
| 多模型協作、複雜表單 | 領域模型 | 無數量限制、命名隔離 |
users[0].name、userMap['key'].prop。ConversionError,可實作 TypeConverter 或全局配置 struts.conversionErrorInterceptors 自定義處理。