Strutsform中如何解決不能定義日期類型變量

這篇文章主要介紹Struts form中如何解決不能定義日期類型變量,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

辰溪ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!

在實際應(yīng)用中,我就發(fā)現(xiàn)Struts form確實連有些簡單的時間都處理不了(不知是我使用的方法不對還是Struts form確實沒有考慮到)。順便你也能了解Struts是怎么把form里的請求參數(shù)populate到ActionForm里面的。

今天下午同事告訴我把有java.util.Date類型屬性的類存入數(shù)據(jù)庫時出錯,把這個屬性刪除就沒有問題了。當(dāng)時我就想到是RequestProcessor在processPopulate()時出錯了,因此在它的這個方法設(shè)了斷點并跟蹤了進去。當(dāng)然,它***要調(diào)用ActionForm的reset()方法,然后調(diào)用實際處理populate(將請求參數(shù)傳給ActionForm)的RequestUtils.populate()方法。RequestUtils的這個靜態(tài)方法***是處理Multipart的(即文件上傳等多部分)的方法,然后將所有的請求都放在叫properties的HashMap里并循環(huán)處理它:

names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String stripped = name;
if (prefix != null) {
if (!stripped.startsWith(prefix)) {
continue;
}
stripped = stripped.substring(prefix.length());
}
if (suffix != null) {
if (!stripped.endsWith(suffix)) {
continue;
}
stripped = stripped.substring(0, stripped.length() - suffix.length());
}
if (isMultipart) {
properties.put(stripped, multipartParameters.get(name));
} else {
properties.put(stripped, request.getParameterValues(name));
}
}

實際處理它們的是下面的:BeanUtils.populate(bean, properties); 其中bean就是接受數(shù)據(jù)的ActionForm,而properties里面則是所有的請求的鍵-值對(鍵和值都是字符串,http協(xié)議的特點)。

再看看BeanUtils的靜態(tài)(類)方法populate是怎么處理的:

// Loop through the property name/value pairs to be set
Iterator names = properties.keySet().iterator();
while (names.hasNext()) {

它是循環(huán)所有的請求參數(shù),把實際的工作又交給了setProperty方法。呵呵,弄了半天,這幫人原來都是代理。

這個方法還是代理嗎?計算了一下它有180行的代碼。這么長應(yīng)該是個實干家了吧,錯!千萬不要被有些人的外表欺騙了!有些人一天上班16個小時,可夠敬業(yè)的,可有8小時在打CS。這個類就是:一上來20多行都在一個if (log.isTraceEnabled()){}里面。

log在這說明一下。Struts form中使用的是Jakarta Commons Logging的包,它使用的優(yōu)先級是:Log4j(4念four好像比較有意義,大概是Logger For Java的意思,我聽有的人年Log si J,感覺很別扭,呵呵),Java 1.4 Logging API,Simple Logging。功能是依次減弱。

建議在寫Action 的execute()或被execute()調(diào)用的業(yè)務(wù)方法中使用Commons Logging 來代替System.out.println()--當(dāng)要你把成百上千的System.out.println()去掉的時候你就會覺得Commons Logging是個多好的東東了。它的用法是:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private/protected static Log log = LogFactory.getLog(DispatchAction.class);

如果你用的是DispatchAction,那你就不要自己定義Log的實例了,因為它已經(jīng)有一個protected的Log實例,直接使用即可。

Struts form使用方法是:

if (log.isInfoEnabled()) {
log.Info("some information.");
}

Logging把消息分為6種級別,debug,error,fatal,info,trace,warn。比如,你想記錄一條消息,它只是為了給用戶一個警告,則可以使用warn。為什么在每個log.Info()前做一次判斷呢?難道如果log級別不允許Info,log.Info()仍然能Info嗎?當(dāng)然不是。它的作用是提高效率。

比如有個消息是計算前一萬個自然數(shù)的和(這種消息可能少見)。用直接log.Info()

 int sum=0;
for(int i=0;i<10000;i++){
sum+=i;
}
log.Info("the sum of form 1 to 10000 is : "_sum);

如果log.Info是不允許的,那求10000個數(shù)的和就白求的。當(dāng)然如果你的計算機很快或和高斯一樣聰明,直接log.Info()也每什么問題。

閑話少說,回到180多行的BeanUtils.setProperty()方法。這個方法先是處理nested屬性,也就是xxx.xxx的請求參數(shù)。我們只看看處理簡單屬性的必須過程。下面這端代碼有點長,但它只做了一件事:將字符串的請求參數(shù)轉(zhuǎn)成ActionForm的類型。比如:你在ActionForm里有個Integer userAge;然后HTTP請求參數(shù)里可能會有http://localhost:8080/xxx.do?userAge=21。傳人的是字符串,目標(biāo)是專程Integer。

首先它當(dāng)然會根據(jù)userAge這個字符串查找相應(yīng)的ActionForm,如果這個ActionForm有個屬性也叫userAge,然后就會把這個userAge的類型存到type里,type的定義是:Class type = null; 得到type的代碼很長,這是因為要它考慮很多情況,例DynaActionForm。

        // Convert the specified value to the required type
Object newValue = null;
if (type.isArray() && (index < 0)) { // Scalar value into array
if (value == null) {
String values[] = new String[1];
values[0] = (String) value;
newValue = ConvertUtils.convert((String[]) values, type);
} else if (value instanceof String) {
String values[] = new String[1];
values[0] = (String) value;
newValue = ConvertUtils.convert((String[]) values, type);
} else if (value instanceof String[]) {
newValue = ConvertUtils.convert((String[]) value, type);
} else {
newValue = value;
}
} else if (type.isArray()) {         // Indexed value into array
if (value instanceof String) {
newValue = ConvertUtils.convert((String) value,
type.getComponentType());
} else if (value instanceof String[]) {
newValue = ConvertUtils.convert(((String[]) value)[0],
type.getComponentType());
} else {
newValue = value;
}
} else {                             // Value into scalar
if ((value instanceof String) || (value == null)) {
newValue = ConvertUtils.convert((String) value, type);
} else if (value instanceof String[]) {
newValue = ConvertUtils.convert(((String[]) value)[0],
type);
} else if (ConvertUtils.lookup(value.getClass()) != null) {
newValue = ConvertUtils.convert(value.toString(), type);// Here is my program's break point
} else {
newValue = value;
}
}

***是:調(diào)用PropertyUtils的一些方法設(shè)置值。下面代碼的***種情況是有索引的,即你在請求參數(shù)里傳了field[0]=123之類的參數(shù),第二種是Map類型的,傳的是map(key)=value之類的參數(shù),最一般的就是調(diào)用第三個方法

 if (index >= 0) {
PropertyUtils.setIndexedProperty(target, propName,
index, newValue);
} else if (key != null) {
PropertyUtils.setMappedProperty(target, propName,
key, newValue);
} else {
PropertyUtils.setProperty(target, propName, newValue);
}

當(dāng)然還可以在跟蹤下去,不過和這個主題沒什么關(guān)系了。大概的流程是:

setProperty()方法再調(diào)用setNestedProperty()方法(還是代理),在調(diào)用setSimpleProperty(),***通過java.lang.reflect包調(diào)用你在ActionForm里寫的setXXX()方法,如setUserAge(Integer userAge)等。

現(xiàn)在說說為什么不能populate java.util.Date類型的數(shù)據(jù)。關(guān)鍵是ConvertUtils.convert(),即上文有注釋的地方。如果這個方法返回的是一個java.util.Date類型的對象,當(dāng)然后面都不會有問題。但我發(fā)現(xiàn)實際運行的結(jié)果是,newValue還是String類型的,因此在后面通過reflection調(diào)用setXXX時出錯。

你或許會奇怪ConvertUtils包竟然連java.util.Date都不支持,我也覺得不可思異。我還以為是我使用的不對,然后進入這個類一看,確實是不支持:

*
*
*
* 
*
* @author Craig R. McClanahan
* @author Ralph Schaer
* @author Chris Audley
* @version $Revision: 1.12 $ $Date: 2003/01/15 21:59:38 $
*/

另外,會不會即時是字符串的,org.apache.commons.beanutils.PropertyUtils.setProperty()也有能力處理呢?

于是又寫了個小程序測試。

public class SetSimplePropertyTest {
public SetSimplePropertyTest() {
}
public static void main(String[] args) {
SetSimplePropertyTest setSimplePropertyTest1 = new SetSimplePropertyTest();
String dateStr="2004-01-01 19:00:00";
test.DataBean dataBean=new DataBean();
try {
org.apache.commons.beanutils.PropertyUtils.setProperty(dataBean,
"receiveTime", dateStr);
}
catch (Exception e){
e.printStackTrace();
}
System.out.println(dataBean.getReceiveTime().toString());
}

運行是拋出異常,證明處理不了。

問題找到了,那該怎么解決呢?當(dāng)然最簡單的方法就是使用ConvertUtils能轉(zhuǎn)的java.sql.DateTime等,比較復(fù)雜一點的方法就是自己寫一個ConvertUtils。當(dāng)然,如果你把日前存成String,那更沒問題,但如果要將它存入數(shù)據(jù)庫,還得轉(zhuǎn)。尤其在使用DAO模式時,我們可能用BeanUtils.CopyProperties()方法實現(xiàn)將一個ActionForm拷貝到一個DTO(or VO)對象中時會很麻煩。

還有一個比較好的方法是,屬性定義成java.util.Date,但為Struts form提高另一個getter/setter方法。這種方法是在middlegen自動生成的JSP頁面看到的。

例如:


private java.util.Date saveDate;
//普通的set/get方法
public void setSaveDate(java.util.Date saveDate){
this.saveDate=saveDate;
}
public java.util.Date getSaveDate(){
return this.saveDate;
}
//為Struts準(zhǔn)備的方法,時期的格式假定是 2000-12-31 23:59:59
public void setSaveDateAsString(String saveDate){
java.text.DateFormat dateFormat =new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.saveDate=dateFormat.parse(saveDate);
}
public String getSaveDateAsString(){
java.text.DateFormat dateFormat =new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return dateFormat.Format(this.saveDate);                
}

然后在JSP中使用:
< ?xml:namespace prefix = html />< html:form action="xxx.do">
< html:text property="saveDateAsString">< /html:text>
< /html:form>< /pre>

以上是“Struts form中如何解決不能定義日期類型變量”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章標(biāo)題:Strutsform中如何解決不能定義日期類型變量
文章路徑:http://muchs.cn/article38/isjhsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、網(wǎng)站排名、商城網(wǎng)站、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)