日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java中struts2日期_Struts2中Date日期转换的问题

發布時間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中struts2日期_Struts2中Date日期转换的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天跑程序的時候莫名其妙的出現了下面的一個異常:

java.lang.NoSuchMethodException:com.ca.agent.model.mybatis.ApprovalInforCangra.setSubDate([Ljava.lang.String;)

這類異常信息在以前是處理過的,按照以前的思路在eclipse的調試模式下看看具體的情況,不過這次比較奇怪,根本沒進入到對應的Action類中就拋出了此異常信息,進一步查找發現,在調用攔截器方法的時候就拋出了此異常信息,還有沒有想明白的就是對應的功能我是測試過好多次的,之前這一塊是沒有任何問題的!不過現在事實是卻拋出了異常信息,一定是那里出錯了,到底是那里哪?查找了大半個下午也沒找到對應的解決方案,應該是我忽略了什么地方,一時半會可能也想不起來了,找位同事幫忙吧!于是找來同事G來幫忙,最終找到了問題的原因!Struts2默認可支持String和Date的轉換,但僅支持短格式和本地化有關日期格式轉換,前幾天我將自己的IE瀏覽器的語言環境改成了英語的!而對于yyyy-MM-dd這種日期類型,在英語語言中是沒法匹配的,由于Struts2匹配日期時,使用了Locale,所以使用英文的語言環境,就導致了此問題的出現,把中文設置為默認語言環境后,再測試,沒問題了!

Web開發會涉及到很多類型轉換的情況。我們知道,頁面中的一切值都是字符串類型,而到后臺,我們需要的可能是其他各種類型;同時,頁面顯示也是字符串類型。這就涉及到Web中基本的類型轉換問題:從String轉換為各種類型與從各種類型轉換為String類型。

在Java Web開發中,進行上述轉換一般有以下幾種:

1、在Servlet中,這一切的轉換我們得自己寫代碼完成;

2、在Struts1.x中,我們通過apache commons-beanutils中的converters來幫助完成這些事情;

3、在Struts2中,使用的則是基于ongl的類型轉換;

……

由 于類型轉換的通用性,因而Web框架都會實現大多數類型的轉換功能,而不需要程序員編碼實現。然而,對于java.util.Date這種類型的轉換,各 大框架似乎做得都不盡如人意。如:在Struts1.x中,該類型的轉換就會有問題,很多人建議使用java.sql.Date這種類型來解決日期轉換的 問題(實際上可以自定義一個類型轉換器來解決該問題)。在Struts2中,這個問題似乎依然存在,也許你從來沒有遇到過。的確,一般人確實不會遇到,會 覺得沒有這個問題。下面就是我遇到的問題與解決方法。

日期類型的轉換,Web開發中幾乎都會遇到,我現在做得項目也不例外。在開發的過程 中,也許就像你一樣,我沒有對日期類型的轉換做任何特殊的處理,而且Struts2也很好的幫我完成了轉換。然而同事測試的時候卻出現了一個“莫名其妙” 的問題:輸入一個常用格式的日期類型yyyy-MM-dd,到后臺卻報錯:找不到對應的set方法—— setEffDate(Ljava.lang.String)。的確,程序中只有setEffDate(java.util.Date)這個方法,沒有 setEffDate(Ljava.lang.String)這個方法。從Ljava.lang.String可以看出,傳到后臺的String類型并沒 有轉換成Date類型,因而報錯。

一開始,我以為是我UT沒做好,于是在自己的電腦上模擬同事的測試,結果一點問題也沒有。這就奇怪了。 經過自己分析,覺得可能是IE瀏覽器的原因,因為同事測試用的是IE,而我用的是FireFox。于是在自己的機子上用IE測試,同時在同事機子上用 FireFox測試,結果這兩次測試都沒有出現上面的問題。雖然沒有找到問題所在,但可以初步肯定:IE的問題,但似乎又不完全是IE的問題,因為在我的 電腦上的IE(版本與同事一樣,都是IE6)沒有上述問題。這就奇怪了,是什么問題呢,真是百思不得其解。

這個時候,我想起了之前遇到的 一個不解得情況:從后臺獲得的日期類型在頁面上顯示時,跟上面情況一樣,在同事的IE中,日期顯示的格式竟然是:yyyy-MM- ddTHH:mm:ss。多了一個T,真是莫名其妙,而且只在同事的IE瀏覽器中出現(當時解決方法是在JS中將'T'替換為空格,沒有去深究,但現在必 須的深究了)。yyyy-MM-ddTHH:mm:ss這種日期格式有嗎?于是查詢JDK:在SimpleDateFormat類中找到了該日期格式,這 種格式是“美國語言環境中日期和時間的模式之一”。原來還真有這種格式。竟然這是美國語言中使用的日期格式,而Struts2是美國人開發的,也許跟這個 有點關系。于是查看Struts2中關于Date類型轉換的源碼。

在XWorkBasicConverter類中

private?Object doConvertToDate(Map context, Object value, Class toType) {

Date result =?null;

if?(value?instanceof?String && value !=?null?&& ((String) value).length() > 0) {

String sa = (String) value;

Locale locale = getLocale(context);

DateFormat df =?null;

if?(java.sql.Time.class?== toType) {

df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);

}?else?if?(java.sql.Timestamp.class?== toType) {

Date check =?null;

SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,

DateFormat.MEDIUM,

locale);

SimpleDateFormat fullfmt =?new?SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,

locale);

SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,

locale);

SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};

for?(SimpleDateFormat fmt : fmts) {

try?{

check = fmt.parse(sa);

df = fmt;

if?(check !=?null) {

break;

}

}?catch?(ParseException ignore) {

}

}

}?else?if?(java.util.Date.class?== toType) {

Date check =?null;

DateFormat[] dfs = getDateFormats(locale);

for?(DateFormat df1 : dfs) {

try?{

check = df1.parse(sa);

df = df1;

if?(check !=?null) {

break;

}

}

catch?(ParseException ignore) {

}

}

}

//final fallback for dates without time

if?(df ==?null) {

df = DateFormat.getDateInstance(DateFormat.SHORT, locale);

}

try?{

df.setLenient(false);?// let's use strict parsing (XW-341)

result = df.parse(sa);

if?(!(Date.class?== toType)) {

try?{

Constructor constructor = toType.getConstructor(new?Class[]{long.class});

return?constructor.newInstance(new?Object[]{Long.valueOf(result.getTime())});

}?catch?(Exception e) {

throw?new?XWorkException("Couldn't create?class?"?+ toType +?" using?default?(long) constructor", e);

}

}

}?catch?(ParseException e) {

throw?new?XWorkException("Could not parse date", e);

}

}?else?if?(Date.class.isAssignableFrom(value.getClass())) {

result = (Date) value;

}

return?result;

}

private?DateFormat[] getDateFormats(Locale locale) {

DateFormat dt1 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);

DateFormat dt2 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);

DateFormat dt3 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);

DateFormat d1 = DateFormat.getDateInstance(DateFormat.SHORT, locale);

DateFormat d2 = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);

DateFormat d3 = DateFormat.getDateInstance(DateFormat.LONG, locale);

DateFormat rfc3399 =?new?SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

DateFormat[] dfs = {dt1, dt2, dt3, rfc3399, d1, d2, d3};?//added RFC 3339 date format (XW-473)

return?dfs;

}

其中SHORT、MEDIUM、LONG在JDK中的DateFormat類中有說明。

從 這句DateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");可以看出,Struts2硬編碼使用了這樣一種格式。然 而,Struts2中這種格式是放在最后的,為啥只有同事的IE瀏覽器測試時使用的是這種格式呢?(在調試時,用同時IE,日期輸入中按這種格式輸入,還 真的沒有問題了)這說明,同事的電腦中,前面六種DateFormat都沒有匹配,查看DateFormat中關于SHORT、MEDIUM、LONG的 說明,可以知道,對于yyyy-MM-dd這種日期類型,在英語語言中是沒法匹配的,由于Struts2匹配日期時,使用了Locale,可見,同事的IE瀏覽器默認的語言環境是英語。一經查看,果然如此,把中文設置為默認語言環境,再測試,沒問題了。終于知道了原因。

個人覺得,Struts2中,最后一種日期模式寫死成美國標準,不是很好。

針 對這個問題,我們沒法要求客戶一定設置中文為默認瀏覽器的語言環境。因而對于Date類型的轉換,可以自己定義一個轉換器。以下來自 http://www.javaeye.com/wiki/struts2/1365-passing-parameters-in-struts2 中的一個類型轉換器定義(不適合國際化的環境),如需要,你可以定義自己的轉換器:

public?class?DateConverter?extends?DefaultTypeConverter {

private?static?final?Logger logger = Logger.getLogger(DateConverter.class);

private?static?final?String DATETIME_PATTERN =?"yyyy-MM-dd HH:mm:ss";

private?static?final?String DATE_PATTERN =?"yyyy-MM-dd";

private?static?final?String MONTH_PATTERN =?"yyyy-MM";

/**

* Convert value between types

*/

@SuppressWarnings("unchecked")

public?Object convertValue(Map ognlContext, Object value, Class toType) {

Object result =?null;

if?(toType == Date.class) {

result = doConvertToDate(value);

}?else?if?(toType == String.class) {

result = doConvertToString(value);

}

return?result;

}

/**

* Convert String to Date

*

* @param value

* @return

*/

private?Date doConvertToDate(Object value) {

Date result =?null;

if?(value?instanceof?String) {

result = DateUtils.parseDate((String) value,?new?String[] { DATE_PATTERN, DATETIME_PATTERN, MONTH_PATTERN });

// all patterns failed, try a milliseconds constructor

if?(result ==?null?&& StringUtils.isNotEmpty((String)value)) {

try?{

result =?new?Date(new?Long((String) value).longValue());

}?catch?(Exception e) {

logger.error("Converting from milliseconds to Date fails!");

e.printStackTrace();

}

}

}?else?if?(value?instanceof?Object[]) {

// let's try to convert the first element only

Object[] array = (Object[]) value;

if?((array !=?null) && (array.length >= 1)) {

value = array[0];

result = doConvertToDate(value);

}

}?else?if?(Date.class.isAssignableFrom(value.getClass())) {

result = (Date) value;

}

return?result;

}

/**

* Convert Date to String

*

* @param value

* @return

*/

private?String doConvertToString(Object value) {

SimpleDateFormat simpleDateFormat =?new?SimpleDateFormat(DATETIME_PATTERN);

String result =?null;

if?(value?instanceof?Date) {

result = simpleDateFormat.format(value);

}

return?result;

}

}

可以將該轉換器注冊為全局的:在classpath下建立xwork-conversion.properties文件,內容為:java.util.Date=你的類型轉換器的完整限定類名

參看:

總結

以上是生活随笔為你收集整理的java中struts2日期_Struts2中Date日期转换的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。