JSP 頁面提交表單,包含日期字段(如 <input type="date" name="birthDate">)。Action 中定義 private Date birthDate; 及對應 Getter/Setter,**後端接收到的 birthDate 為 null**,無法自動類型轉換。
Struts2 默認類型轉換器 DateConverter 要求輸入字符串**嚴格匹配預設格式** (通常為 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)。前端提交的格式可能因瀏覽器、Locale、type="date" 實現差異而不匹配(如 MM/dd/yyyy、帶時區等),導致轉換拋異常被靜默吞噬,屬性最終為 null。
public class UserAction extends ActionSupport {
// 1. 定義 String 屬性接收原始輸入
private String birthDateStr;
// 2. 真正的 Date 屬性供業務使用
private Date birthDate;
// Getter/Setter
public String getBirthDateStr() { return birthDateStr; }
public void setBirthDateStr(String birthDateStr) { this.birthDateStr = birthDateStr; }
public Date getBirthDate() { return birthDate; }
public void setBirthDate(Date birthDate) { this.birthDate = birthDate; }
@Override
public String execute() {
// 3. 在業務邏輯中手動解析,可控性最強
if (birthDateStr != null && !birthDateStr.trim().isEmpty()) {
try {
// 嘗試多種常見格式
SimpleDateFormat[] formats = {
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy/MM/dd"),
new SimpleDateFormat("MM/dd/yyyy")
};
for (SimpleDateFormat fmt : formats) {
try {
fmt.setLenient(false);
this.birthDate = fmt.parse(birthDateStr.trim());
break; // 解析成功跳出
} catch (ParseException ignored) {}
}
} catch (Exception e) {
addFieldError("birthDateStr", "日期格式無效,請使用 yyyy-MM-dd");
return INPUT;
}
}
// 繼續業務邏輯...
return SUCCESS;
}
}
public class FlexibleDateConverter extends StrutsTypeConverter {
private static final String[] PATTERNS = {
"yyyy-MM-dd", "yyyy/MM/dd", "MM/dd/yyyy", "yyyy-MM-dd HH:mm:ss"
};
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if (values == null || values.length == 0) return null;
String val = values[0].trim();
for (String pattern : PATTERNS) {
try {
SimpleDateFormat fmt = new SimpleDateFormat(pattern);
fmt.setLenient(false);
return fmt.parse(val);
} catch (ParseException ignored) {}
}
throw new IllegalArgumentException("無法解析日期: " + val);
}
@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 (放在 src/main/resources)
java.util.Date=com.yourpkg.FlexibleDateConverter
或在 Action 字段上:@TypeConversion(converter = "com.yourpkg.FlexibleDateConverter")。
<input type="date"> 瀏覽器原生日期選擇器,**提交格式固定為 yyyy-MM-dd (ISO 8601)**,最兼容 Struts2 默認轉換器。yyyy-MM-dd**。type="text" 手動輸入,格式不可控。「最後的解決方案是在後台定義一個字符串,然後手動轉成日期」 是最直接、可控、不依賴框架默認行為的做法。若項目中日期字段極多,建議實現 全局自定義 TypeConverter 統一處理多格式解析,一次配置全項目受益。