HTTP 參數皆為字串,但 Action 屬性可能是 int、Date、List、自定義物件等。Struts 2 在參數注入前,自動進行字串→目標型別轉換,失敗則收集錯誤到 fieldErrors。
| 目標型別 | 說明 |
|---|---|
| 基本型別 & 包裝類 | int/Integer, long/Long, double/Double, float/Float, boolean/Boolean, char/Character |
| String | 直接指派 |
| Date | 依 Locale SHORT 格式(如 yyyy/MM/dd) |
| 陣列 | 元素預設 String,可配合自定義轉換器 |
| Collection (List/Set) | 元素預設 String |
| Map | Key/Value 預設 String |
ognl.TypeConverter(雙向轉換)ognl.DefaultTypeConverter(單一方法 convertValue(Map, Object, Class))org.apache.struts2.util.StrutsTypeConverter(兩個抽象方法 convertFromString/convertToString)ActionName-conversion.properties檔案置於 Action 同包:
# UserAction-conversion.properties
birthday=com.demo.converter.MyDateConverter
user=com.demo.converter.UserConverter
Key 為 Action 屬性名,Value 為轉換器全限定名。
xwork-conversion.properties檔案置於 src/(編譯後在 WEB-INF/classes):
# xwork-conversion.properties
java.util.Date=com.demo.converter.GlobalDateConverter
com.demo.model.User=com.demo.converter.UserConverter
Key 為目標型別全名,對所有 Action 生效。
@Conversion(type = MyDateConverter.class)
private Date birthday;
需在 struts.xml 啟用:<constant name="struts.enable.ognl.typeConverter" value="true" />。
public class MyDateConverter extends StrutsTypeConverter {
private static final String PATTERN = "yyyyMMdd"; // 目標格式
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if (values == null || values.length == 0) return null;
SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
try {
return sdf.parse(values[0]);
} catch (ParseException e) {
return null; // 或拋出 ConversionException
}
}
@Override
public String convertToString(Map context, Object o) {
if (o instanceof Date) {
return new SimpleDateFormat("yyyy年MM月dd日").format((Date) o);
}
return "";
}
}
# xwork-conversion.properties
java.util.Date=com.demo.converter.MyDateConverter
如此所有 Date 屬性自動套用 yyyyMMdd 解析、yyyy年MM月dd日 輸出。
public class User {
private Integer id;
private String name;
// getter/setter/toString 省略
}
public class UserConverter extends StrutsTypeConverter {
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if (values == null || values.length == 0) return null;
String[] parts = values[0].split(",");
if (parts.length != 2) return null;
User u = new User();
u.setId(Integer.valueOf(parts[0].trim()));
u.setName(parts[1].trim());
return u;
}
@Override
public String convertToString(Map context, Object o) {
if (o instanceof User) {
User u = (User) o;
return u.getId() + "," + u.getName();
}
return "";
}
}
# UserAction-conversion.properties
user=com.demo.converter.UserConverter
values 為何是 String[]?因 HTTP 允許同名參數多值(如 checkbox),request.getParameterValues() 回傳陣列。ConversionException 或回傳 null,Struts 2 會自動加入 fieldErrors。Element_conversion.properties(元素型別級),或於 xwork-conversion.properties 註冊 java.util.List=com.demo.ListConverter(較少用)。prepare() 或 Service 層處理。struts.devMode=true,控制台會印出轉換器呼叫堆疊。fieldErrors 是否含 conversionError 關鍵字。convertFromString() 驗證邏輯。