在示范中心項目中,我們把ActionForm中日期類型的字段指定為String類型,而在對應的JavaBean中指定為java.sql.Date類型。當用戶提交表單的時候,在Action里使用BeanUtils.copyProperties()方法從ActionForm構造JavaBean對象(詳見利用BeanUtils在對象間復制屬性)。這個方法在大部分時候都很好,但有一個問題,就是當用戶沒有填寫日期類型字段時(而該字段并非必填),validator不會提出警告,而在copyProperties()時會報類型轉換異常,原因是這時ActionForm中的該字段的值是空字符串(""),負責字符串向Date轉換的SqlDateConverter類調用Date.valueOf("")方法,顯然""是無法轉換為日期的,所以會拋出異常。

通過查看代碼和資料,我發現這個問題的解決方法其實非常簡單。只要把帶缺省值參數的SqlDateConverter重新注冊一下,覆蓋原有的注冊信息就可以了,這個注冊語句一般是寫在系統初試化的地方,對于Struts應用程序,當然做在PlugIn里最方便。代碼如下:

package?etc;

import?javax.servlet.ServletException;
import?org.apache.commons.beanutils.ConvertUtils;
import?org.apache.commons.beanutils.converters.SqlDateConverter;
import?org.apache.struts.action.ActionServlet;
import?org.apache.struts.action.PlugIn;
import?org.apache.struts.config.ModuleConfig;

public?class?ConverterPlugIn?implements?PlugIn{

????public?
void ?init(ActionServlet?servlet,?ModuleConfig?config)?throws?ServletException?{
????????ConvertUtils.register(
new ?SqlDateConverter( null ),java.sql.Date.class);
????}

????public?
void ?destroy()?{
????????ConvertUtils.deregister();
????}
}

注意SqlDateConverter的構造方法是帶有參數null的,這表示遇到不能解析的字符串就返回空值。而deregister()方法的作用是恢復ConvertUtils的缺省注冊表。為了使這個PlugIn起作用,要在struts-config.xml里增加一句話:

< plug - in ?className = " etc.ConverterPlugIn " ? />

日期字段往往會給我們的開發帶來麻煩,其實在Struts應用程序里,只要把這些轉換類搞熟了,總可以找到很方便的辦法。常見的問題還有如何指定日期輸入格式,怎樣處理java.util.Date的轉換,等等,在這個鏈接里有解決這些問題的方法,道理都是一樣的。