表單提交 java.util.Date 字段時,Struts 1 內置轉換器不支持,報錯:
java.lang.IllegalArgumentException: Cannot invoke ...setUtilDate - argument type mismatch
public class UtilDateConverter implements Converter {
public Object convert(Class type, Object value) {
if (value instanceof Date) {
return value;
}
if (value instanceof String) {
try {
return new SimpleDateFormat("yyyy-MM-dd").parse((String) value);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}
String → Date 解析(格式 yyyy-MM-dd)。Date 直接返回。null 由驗證層處理。同上,實現 org.apache.commons.beanutils.Converter。
public class UtilServlet extends HttpServlet {
public void init() throws ServletException {
ConvertUtils.register(new UtilDateConverter(), java.util.Date.class);
}
}
<servlet> <servlet-name>UtilServlet</servlet-name> <servlet-class>com.tgb.struts1.UtilServlet</servlet-class> <load-on-startup>10</load-on-startup> <!-- 關鍵:Tomcat 啟動時加載註冊 --> </servlet>
load-on-startup > 0 確保在 Struts 初始化前完成轉換器註冊。commons-beanutils 包。
public class UtilDateConverterPlugin implements PlugIn {
public void init(ActionServlet servlet, ModuleConfig config) throws ServletException {
ConvertUtils.register(new UtilDateConverter(), java.util.Date.class);
}
public void destroy() { }
}
<plug-in className="com.tgb.struts1.UtilDateConverterPlugin" />
init(),無需額外 Servlet 配置。JSP 表單提交 java.util.Date 字段:
<input type="text" name="utilDate" />
兩種方式均可正常綁定,ActionForm 中 setUtilDate(Date) 正確接收解析後的 Date 對象。
Struts 1 利用 Commons BeanUtils.ConvertUtils 作為統一類型轉換註冊中心:
Converter 接口(策略模式)。Converter,註冊到 ConvertUtils。BeanUtils.populate() 填充表單時自動查找並調用對應轉換器。這體現了 開閉原則:對擴展開放(新增 Converter),對修改關閉(不動框架代碼)。
SimpleDateFormat 改為多模式嘗試(yyyy-MM-dd、yyyy/MM/dd、MM/dd/yyyy)。SimpleDateFormat 非線程安全,改用 ThreadLocal 或 DateTimeFormatter (Java 8+)。LocalDate、LocalDateTime、BigDecimal 等常用類型批量註冊。Struts 1 缺失 java.util.Date 轉換器是常見坑點。通過實現 Converter 接口並選擇 Servlet init() 或 PlugIn 兩種方式之一註冊到 ConvertUtils,即可完美解決。PlugIn 方式更符合 Struts 架構,推薦生產環境使用。此過程生動展示了策略模式與開閉原則在框架擴展點中的實戰應用。