HTTP 協議無類型概念,所有請求參數到達服務端均為 String 或 String[]。Struts2 通過強大的類型轉換機制,自動將其轉換為 Action 屬性所需的目標類型。本文系統梳理從內置基本類型轉換到自定義轉換器、複雜對象圖、集合泛型、JSON 數據的完整體系,並給出生產級錯誤處理與最佳實踐。
| 目標類型 | 轉換行為 | 失敗時默認值 |
|---|---|---|
基本類型 int, double, boolean... | 自動調用對應 valueOf/parseXxx | 0 / 0.0 / false |
包裝類型 Integer, Double, Boolean... | 同基本類型 | null |
String | 直接賦值 | "" |
Date | 按 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 解析 | null |
錯誤處理機制:Action 實現 ValidationAware(ActionSupport 已實現)時,轉換失敗會:
ActionErrors/FieldErrorsresult name="input"(未配置則 404)
public class MyTypeConverter extends StrutsTypeConverter {
// String[] → 目標對象
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if (Person.class == toClass) {
Person p = new Person();
String[] parts = values[0].split(",");
p.setUserName(parts[0]);
p.setAge(Integer.parseInt(parts[1]));
return p;
}
if (Address.class == toClass) { ... }
return null;
}
// 目標對象 → String(用於表單回顯)
@Override
public String convertToString(Map context, Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return p.getUserName() + "," + p.getAge();
}
return "";
}
}
| 作用域 | 配置文件位置 | 命名規則 | 優先級 |
|---|---|---|---|
| 類級別 | Action 同包目錄 | ActionName-conversion.properties | 高 |
| 全局級別 | 類路徑根目錄 | xwork-conversion.properties | 低 |
| Action 結構 | JSP 字段命名 | 轉換器註冊 |
|---|---|---|
List | persons[0].userName, persons[0].age... | Person 轉換器(類級別) |
Person addresses: List (ModelDriven) | addresses[0].addressName... | Address 轉換器(在 Person-conversion.properties 中) |
關鍵規則:集合元素轉換復用元素類型的轉換器,框架自動根據泛型類型推斷。
// pom.xml
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.x</version>
</dependency>
// struts.xml
<package name="json" extends="json-default">
<action name="saveUser" class="com.example.UserAction" method="save">
<result type="json">
<param name="root">resultMap</param>
</result>
</action>
</package>
// 前端 AJAX
$.post("saveUser", {userName: "Tom", age: 25}, function(data) { ... }, "json");
JSON Plugin 內置反序列化器,自動將 JSON 映射為 Action 屬性對象(支援巢狀、集合),無需手寫轉換器。
# ActionName.properties
invalid.fieldvalue.age=年齡必須為數字
invalid.fieldvalue.person=人員信息格式錯誤
# JSP 展示
<s:fielderror fieldName="age" /> // 顯示該字段錯誤
<s:actionerror /> // 顯示全局錯誤
值棧中錯誤結構:Map,可通過 OGNL 遍歷:fieldErrors['age'][0]。
xwork-conversion.properties),避免分散維護obj.prop、list[0].prop、map['key'].prop<s:fielderror> 統一渲染掌握 Struts2 類型轉換體系,能讓你從「手動 request.getParameter + 字符串解析」的原始狀態進化到「聲明式自動映射」的高效開發模式,專注於業務邏輯而非參數綁定瑣事。