日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Struts2中的參數(shù)傳遞

 燮羽 2010-12-07
本篇主要通過實例來講述Struts2中各種各樣的參數(shù)傳遞。這個參數(shù)傳遞的過程主要指數(shù)據(jù)從View層傳遞到Control層時Struts2的工作方式。根據(jù)前兩篇文章的知識,我們知道,Struts2完成參數(shù)傳遞處理工作的基礎是OGNL和ValueStack。而在這個過程中,我也把Struts2所要做的工作大致歸納為兩個方面: 

1. 對OGNL操作進行封裝,完成OGNL表達式所表示的值到Java對象的值傳遞機制 

2. 在參數(shù)傳遞的過程中,做恰當?shù)念愋娃D(zhuǎn)化,保證頁面上的字符串能夠轉(zhuǎn)化成各式各樣的Java對象
 

接下來,通過四個不同的角度,來具體講述Struts2在這兩個方面的工作。

最簡單的參數(shù)傳遞 

使用OGNL的最基本的功能,就能完成普通的Java對象的賦值工作。Struts2在內(nèi)部已經(jīng)完成了OGNL的基本封裝。這些封裝包括對OGNL表達式到Java對象的賦值機制,以及對基本的Java類型的類型轉(zhuǎn)化支持。這些基本類型包括String、Number(以及其基本類型int、float、double等)、Boolean(boolean)、數(shù)組、Class、Date等類型。 

在這里我想額外強調(diào)的是XWork對JDK5.0中的Enum類型和Date類型的支持。 

Enum類型 

枚舉類型是JDK5.0引入的新特性。枚舉類型也能解決很多實際問題,是J2EE編程中的最佳實踐之一。XWork中,有一個專門的EnumTypeConverter負責對Enum類型的數(shù)據(jù)進行轉(zhuǎn)化。 

Java代碼 
  1. public class EnumTypeConverter extends DefaultTypeConverter {  
  2.   
  3.     /** 
  4.      * Converts the given object to a given type. How this is to be done is implemented in toClass. The OGNL context, o 
  5.      * and toClass are given. This method should be able to handle conversion in general without any context or object 
  6.      * specified. 
  7.      * 
  8.      * @param context - OGNL context under which the conversion is being done 
  9.      * @param o       - the object to be converted 
  10.      * @param toClass - the class that contains the code to convert to enumeration 
  11.      * @return Converted value of type declared in toClass or TypeConverter.NoConversionPossible to indicate that the 
  12.      *         conversion was not possible. 
  13.      */  
  14.     public Object convertValue(Map context, Object o, Class toClass) {  
  15.         if (o instanceof String[]) {  
  16.             return convertFromString(((String[]) o)[0], toClass);  
  17.         } else if (o instanceof String) {  
  18.             return convertFromString((String) o, toClass);  
  19.         }  
  20.   
  21.         return super.convertValue(context, o, toClass);  
  22.     }  
  23.   
  24.     /** 
  25.      * Converts one or more String values to the specified class. 
  26.      * @param value - the String values to be converted, such as those submitted from an HTML form 
  27.      * @param toClass - the class to convert to 
  28.      * @return the converted object 
  29.      */  
  30.     public java.lang.Enum convertFromString(String value, Class toClass) {  
  31.         return Enum.valueOf(toClass, value);  
  32.     }  
  33.   
  34. }  


有了這個類,我們就可以比較輕松的對枚舉類型進行數(shù)據(jù)賦值了。 

Java代碼 
  1. public enum Gender {  
  2.       
  3.     MALE, FEMALE  
  4.   
  5. }  


Html代碼 
  1. <form method="post" action="/struts-example/enum-conversion.action">  
  2.     <input type="text" name="user.name" value="downpour" />  
  3.     <select name="user.gender">  
  4.        <option value="MALE"></option>  
  5.        <option value="FEMALE"></option>  
  6.     </select>  
  7.     <input type="submit" value="submit" />  
  8. </form>  


Java代碼 
  1. public class EnumConversionAction extends ActionSupport {  
  2.   
  3.     private static final Log logger = LogFactory.getLog(Policy.class);  
  4.       
  5.     private User user;  
  6.       
  7.     /* (non-Javadoc) 
  8.      * @see com.opensymphony.xwork2.ActionSupport#execute() 
  9.      */  
  10.     @Override  
  11.     public String execute() throws Exception {  
  12.         logger.info("user's gender:" + user.getGender());  
  13.         return super.execute();  
  14.     }  
  15.       
  16.     // setters and getters  
  17. }  


通過上面的代碼,就完成了對枚舉類型的賦值。不過這里有一點需要特別指出:那就是XWork在XWork-2.1.X的版本之前,枚舉類型不被默認支持。如果你需要獲得枚舉類型的自動賦值,還需要增加一個配置文件xwork-conversion.properties到classpath下: 
Java代碼 
  1. java.lang.Enum=com.opensymphony.xwork2.util.EnumTypeConverter  

對于使用新的版本的XWork的朋友,則不需要增加這個配置文件。 

Date類型 

XWork默認是支持Date類型的轉(zhuǎn)化的。不過從源碼上來看,貌似我們很難用上它默認的類型轉(zhuǎn)化。 

Java代碼 
  1. private Object doConvertToDate(Map context, Object value, Class toType) {  
  2.         Date result = null;  
  3.   
  4.         if (value instanceof String && value != null && ((String) value).length() > 0) {  
  5.             String sa = (String) value;  
  6.             Locale locale = getLocale(context);  
  7.   
  8.             DateFormat df = null;  
  9.             if (java.sql.Time.class == toType) {  
  10.                 df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);  
  11.             } else if (java.sql.Timestamp.class == toType) {  
  12.                 Date check = null;  
  13.                 SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,  
  14.                         DateFormat.MEDIUM,  
  15.                         locale);  
  16.                 SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,  
  17.                         locale);  
  18.   
  19.                 SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,  
  20.                         locale);  
  21.   
  22.                 SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};  
  23.                 for (int i = 0; i < fmts.length; i++) {  
  24.                     try {  
  25.                         check = fmts[i].parse(sa);  
  26.                         df = fmts[i];  
  27.                         if (check != null) {  
  28.                             break;  
  29.                         }  
  30.                     } catch (ParseException ignore) {  
  31.                     }  
  32.                 }  
  33.             } else if (java.util.Date.class == toType) {  
  34.                 Date check = null;  
  35.                 SimpleDateFormat d1 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);  
  36.                 SimpleDateFormat d2 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);  
  37.                 SimpleDateFormat d3 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);  
  38.                 SimpleDateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");  
  39.                 SimpleDateFormat[] dfs = {d1, d2, d3, rfc3399}; //added RFC 3339 date format (XW-473)  
  40.                 for (int i = 0; i < dfs.length; i++) {  
  41.                     try {  
  42.                         check = dfs[i].parse(sa);  
  43.                         df = dfs[i];  
  44.                         if (check != null) {  
  45.                             break;  
  46.                         }  
  47.                     }  
  48.                     catch (ParseException ignore) {  
  49.                     }  
  50.                 }  
  51.             }  
  52.             //final fallback for dates without time  
  53.             if (df == null) {  
  54.                 df = DateFormat.getDateInstance(DateFormat.SHORT, locale);  
  55.             }  
  56.             try {  
  57.                 df.setLenient(false); // let's use strict parsing (XW-341)  
  58.                 result = df.parse(sa);  
  59.                 if (!(Date.class == toType)) {  
  60.                     try {  
  61.                         Constructor constructor = toType.getConstructor(new Class[]{long.class});  
  62.                         return constructor.newInstance(new Object[]{new Long(result.getTime())});  
  63.                     } catch (Exception e) {  
  64.                         throw new XWorkException("Couldn't create class " + toType + " using default (long) constructor", e);  
  65.                     }  
  66.                 }  
  67.             } catch (ParseException e) {  
  68.                 throw new XWorkException("Could not parse date", e);  
  69.             }  
  70.         } else if (Date.class.isAssignableFrom(value.getClass())) {  
  71.             result = (Date) value;  
  72.         }  
  73.         return result;  
  74.     }  


這段代碼就是XWork處理將String轉(zhuǎn)成Date類型的過程,從整個過程上來看,我們很難用上這段代碼,因為我們在界面上的Date類型的表現(xiàn)形式往往是:'yyyy-MM-dd'或者相關(guān)的形式,很明顯,上面的流程無法匹配這樣的日期類型。 

所以,針對Date,我們往往會自定義一個日期轉(zhuǎn)化的類進行處理,這個在下面會有具體的介紹。

Array、List、Map等容器類型的參數(shù)傳遞 Top

除了簡單的基于JavaBean方式的參數(shù)傳遞支持,Struts2還支持對Array、List、Map等容器類型的數(shù)據(jù)結(jié)構(gòu)做數(shù)據(jù)賦值。不過歷史一路走來,XWork針對容器類型的數(shù)據(jù)賦值一直有變化,讓我們慢慢解讀這些變化,從而也來看看編程思路是如何改變的。 

1. 2004年,XWork-1.0.X的年代 

當時XWork所支持的針對容器的數(shù)據(jù)賦值還比較土。這方面moxie在論壇上有一篇文章專門來講述:http://www./topic/8770。 

總的來說,那個年代對于容器的數(shù)據(jù)賦值,需要依賴于XWork的輔助類。我們可以看到,如果你要對List進行賦值,需要新建一個XWorkList的實現(xiàn)類,并把所需要進行數(shù)據(jù)賦值的Java類傳遞到XWorkList的構(gòu)造函數(shù)中。而對Map等對象的賦值,也同理可得。 

這種數(shù)據(jù)賦值的方式的優(yōu)缺點都非常明顯。優(yōu)點在于簡單,你不需要額外定義任何其他的內(nèi)容,而是直接使用XWork的輔助類來實現(xiàn)類型轉(zhuǎn)化。缺點在于擴展性很弱,很明顯,針對某一個具體的容器,就需要一個XWork的實現(xiàn)類,List有XWorkList對應,Map有XWorkMap對應。甚至在那個時候,還沒有Set的支持,因為沒有XWorkSet的實現(xiàn)。所以使用這種方式,在擴展性方面需要遭受嚴重的考驗。 

2. 2006年,XWork-2.0.X的年代 

也許是XWork團隊看到了擴展性上的問題,所以在XWork和Webwork同時升級以后,采用了新的方式來處理容器賦值。而此時,Javaeye上也涌現(xiàn)出了新的文章,Tin同學對新的方式做了詳細的表述:http://www./topic/17939。 

不過這個新的整合方式似乎并不被大家所看好。 

lllyq 寫道
我覺得XWorkList, XWorkMap還是很有用的,挺好的設計,其實沒有必要deprecated。


moxie 寫道
集合支持不向下兼容。XWorkList已經(jīng)是@deprecated,用它就錯,還不如直接刪除掉。在webwork2.2中,它需要為集合另外配置一個conversion.properties文件。真不明白,這樣有什么優(yōu)點?


這種新的整合方式,實際上只是解決了針對容器賦值,不需要依賴XWork的輔助類這樣的一個問題,不過其付出的代價,卻是多了一個配置文件,這也讓人非常郁悶。好好的類型轉(zhuǎn)化,平白無故多出了一個同package下的配置文件,這也無形中增加了編程的復雜度。 

3. 現(xiàn)在,擁抱了泛型和Annotation的年代 

實際上,在XWork發(fā)展到XWork-2.0.X之后,也開始注重了對泛型和Annotation的支持。所以,容器類型的轉(zhuǎn)化,我們也可以嘗試一下使用JDK的新特性來進行,當然這也是目前最為推薦的做法。 

下面分別給出使用泛型和Annotation的代碼示例: 

Html代碼 
  1. <form method="post" action="/struts-example/ognl-collection-conversion.action">  
  2.     <input type="text" name="users[0].name" value="aaa" />  
  3.     <input type="text" name="users[1].name" value="bbb" />  
  4.     <input type="text" name="users2[0].name" value="ccc" />  
  5.     <input type="text" name="users2[1].name" value="ddd" />  
  6.     <input type="text" name="userMap['user1'].name" value="eee" />  
  7.     <input type="text" name="userMap['user2'].name" value="fff" />  
  8.     <input type="text" name="userMap2['user3'].name" value="ggg" />  
  9.     <input type="text" name="userMap2['user4'].name" value="hhh" />  
  10.     <input type="submit" value="submit" />  
  11. </form>  


Java代碼 
  1. public class OgnlConversionAction extends ActionSupport {  
  2.   
  3.     private static final long serialVersionUID = 4396125455881691845L;  
  4.   
  5.     private static final Log logger = LogFactory.getLog(Policy.class);  
  6.       
  7.     private List<User> users;  
  8.       
  9.     @Element(value = User.class)  
  10.     private List users2;  
  11.       
  12.     private Map<String, User> userMap;  
  13.       
  14.     @Element(value = User.class)  
  15.     private Map userMap2;  
  16.       
  17.     /* (non-Javadoc) 
  18.      * @see com.opensymphony.xwork2.ActionSupport#execute() 
  19.      */  
  20.     @Override  
  21.     public String execute() throws Exception {  
  22.           
  23.         // -> aaa  
  24.         logger.info("users[0].name : " + users.get(0).getName());  
  25.         // -> bbb  
  26.         logger.info("users[1].name : " + users.get(1).getName());  
  27.         // -> ccc  
  28.         logger.info("users2[0].name : " + ((User)users2.get(0)).getName());  
  29.         // -> ddd  
  30.         logger.info("users2[1].name : " + ((User)users2.get(1)).getName());  
  31.           
  32.         // -> [user1, user2]  
  33.         logger.info("userMap.key : " + userMap.keySet());  
  34.         // -> eee  
  35.         logger.info("userMap.key = " + "user1" + " : " + "userMap.value(user1's name) = " + userMap.get("user1").getName());  
  36.         // -> fff  
  37.         logger.info("userMap.key = " + "user2" + " : " + "userMap.value(user2's name) = " + userMap.get("user2").getName());  
  38.         // -> [user3, user4]  
  39.         logger.info("userMap2.key : " + userMap2.keySet());  
  40.         // -> ggg  
  41.         logger.info("userMap2.key = " + "user3" + " : " + "userMap.value(user3's name) = " + ((User)userMap2.get("user3")).getName());  
  42.         // -> hhh  
  43.         logger.info("userMap2.key = " + "user4" + " : " + "userMap.value(user4's name) = " + ((User)userMap2.get("user4")).getName());  
  44.           
  45.         return super.execute();  
  46.     }  
  47.       
  48.     // setters and getters  
  49. }  


上面的代碼中,我們可以看到,如果你使用泛型,那么你無需再使用任何額外的配置文件或者Annotation,XWork會把一切都為你準備好。如果你沒有使用泛型,那么你可以使用Annotation來指定你需要進行轉(zhuǎn)化的對象類型。其中,對Map對象使用Annotation時,Element中的value所對應的值,是Map中的value所對應的class。 

由此可見,泛型和Annotation,在一定程度上,還是可以簡化我們很多工作的。 

文件上傳 

文件上傳其實也是參數(shù)傳遞的一種,所以從方案上來講,Struts2同樣使用了一個攔截器來處理。而這個攔截器,同樣來自于原來的Webwork,基本上沒有做什么很大的改變。有關(guān)這個攔截器的詳細內(nèi)容,我們也留一個懸念,在后續(xù)章節(jié)中詳細講解。目前,你只要知曉,這個攔截器能幫助你完成一切文件上傳相關(guān)的機制。 

早在2005年,Quake Wang就對Webwork的文件上傳機制有了詳細的講解:http://www./topic/10697 

在這里我簡單小結(jié)一下在進行文件上傳時的三大要點: 

1. 在配置文件上傳時,攔截器的順序非常關(guān)鍵 

Xml代碼 
  1. <interceptor-stack name="uploadStack">    
  2.     <interceptor-ref name="upload"/>                    
  3.     <interceptor-ref name="defaultStack"/>    
  4. </interceptor-stack>  


具體來說,upload的攔截器,必須在params的攔截器之前 

2. 攔截器額外提供了一些額外的文件信息 

Quake Wang 寫道
ContentType: 文件的ContentType(可以用在做download的時候) 
FileName: 實際的文件名 
在上面的action例子里, 那么有uploadFilesContentType和uploadFilesFileName這2個屬性, 也能夠被自動綁定


3. 攔截器提供的文件上傳功能,你得到的是一個臨時文件 

robbin 寫道
在webwork的file upload 攔截器功能中,它提供的File只是一個臨時文件,Action執(zhí)行之后就會被自動刪除,因此你必須在Action中自己出來文件的存儲問題,或者寫到服務器的某個目錄,或者保存到數(shù)據(jù)庫中。如果你準備寫到服務器的某個目錄下面的話,你必須自己面臨著處理文件同名的問題


而時代發(fā)展到Struts2的年代,對于文件上傳的整體機制沒有做什么改變。只是Struts2將apache的common-fileupload作為了其默認的文件上傳的機制。 

例子歸例子,實際情況中,我們還是會遇到一些問題: 

1. 默認實現(xiàn)中,文件和文件信息是分開表述的,對于后臺處理來說,不是非常方便 

2. common-fileupload的實現(xiàn),雖然提供了文件上傳的機制,也可以讓你得到文件的一些屬性信息,但是它無法得到客戶端的上傳路徑 

對于第一個問題,我們可以使用OGNL的特性,將這些文件和文件名等文件信息做封裝: 

Java代碼 
  1. public class FileComponent implements Serializable {  
  2.   
  3.     private static final long serialVersionUID = 4594003082271182188L;  
  4.   
  5.     private File upload;  
  6.   
  7.     private String fileName;  
  8.       
  9.     /** 
  10.      * The default constructor 
  11.      */  
  12.     public FileComponent() {  
  13.   
  14.     }  
  15.   
  16.     /** 
  17.      * @return Returns the upload. 
  18.      */  
  19.     public File getUpload() {  
  20.         return upload;  
  21.     }  
  22.   
  23.     /** 
  24.      * @return Returns the fileName. 
  25.      */  
  26.     public String getFileName() {  
  27.         return fileName;  
  28.     }  
  29.       
  30.     /** 
  31.      * @param upload 
  32.      *            The upload to set. 
  33.      */  
  34.     public void setUpload(File upload) {  
  35.         this.upload = upload;  
  36.     }  
  37.   
  38.     /** 
  39.      * @param fileName 
  40.      *            The fileName to set. 
  41.      */  
  42.     public void setFileName(String fileName) {  
  43.         this.fileName = fileName;  
  44.     }  
  45.   
  46.     /** 
  47.      * @param fileName 
  48.      *            The fileName to set. 
  49.      */  
  50.     public void setUploadFileName(String uploadFileName) {  
  51.         this.fileName = uploadFileName;  
  52.     }  
  53. }  


在這個類中,我定義了upload表示上傳的文件,fileName表示上傳文件的文件名。請注意我整個文件中的最后一個方法:setUploadFileName。這個方法將保證FileUploadInterceptor在運行時,能夠正確設置上傳的文件名。 

Java代碼 
  1. /** 
  2.  * @param fileName 
  3.  *            The fileName to set. 
  4.  */  
  5. public void setUploadFileName(String uploadFileName) {  
  6.     this.fileName = uploadFileName;  
  7. }  


這樣,在Action中,我們將面對一個個完整的fileComponent對象,其中包括文件的引用、文件名稱和其他文件信息。這樣就不會因為上傳多個文件而手足無措,你只需要使用fileComponent數(shù)組,就能輕松對上傳的文件進行管理,而避免了在Action中書寫許多個文件、文件名等屬性了。 

對于第二個問題,目前我也沒有找到很好的方法。我所采用的方式與Yulimin是一致的: 

Yulimin 寫道
我現(xiàn)在的做法是表單中增加了一個隱藏域,當用戶文件選擇后,利用JS截取到用戶選擇的文件名,然后一起提交上去。 
不知道有沒有最終的解決方法?

自定義的類型轉(zhuǎn)化實現(xiàn) 

Struts2在處理參數(shù)傳遞的過程中,需要完成類型轉(zhuǎn)化,保證頁面上的字符串能夠轉(zhuǎn)化成各式各樣的Java對象。而這一點,其實也是由OGNL完成的。還記得我們在講述OGNL的基礎知識的時候列出來過的一個接口嘛? 

Java代碼 
  1. /** 
  2.  * Appends the standard naming context for evaluating an OGNL expression 
  3.  * into the context given so that cached maps can be used as a context. 
  4.  * 
  5.  * @param root the root of the object graph 
  6.  * @param context the context to which OGNL context will be added. 
  7.  * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE> 
  8.  *         set appropriately 
  9.  */  
  10. public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context );  


在這個接口中,我們可以在使用OGNL的時候,注冊針對某個Class級別的自己實現(xiàn)的TypeConverter,這樣,OGNL就會在進行設值計算和取值計算的時候,使用自定義的類型轉(zhuǎn)化方式了。讓我們來看看TypeConverter的接口定義: 

Java代碼 
  1. /** 
  2.  *  context - OGNL context under which the conversion is being done 
  3.  *  target - target object in which the property is being set 
  4.  *  member - member (Constructor, Method or Field) being set 
  5.  *  propertyName - property name being set 
  6.  *  value - value to be converted 
  7.  *  toType - type to which value is converted  
  8.  */  
  9. public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType);  


知道了原理,就簡單了,我們可以自己實現(xiàn)一個TypeConverter的實現(xiàn)類,并且在Struts2中注冊一下使用這個TypeConverter的Java類型的對應關(guān)系,我們就可以完成自定義的類型轉(zhuǎn)化了。 

具體的例子,可以參考一下Quake Wang同學在2005年時的一篇文章:http://www./topic/10507。文章針對的是Webwork2,但是無論是實現(xiàn)方式還是操作步驟,與Struts2是完全相同的。值得提醒的是,這篇文章的回復也非常有價值,在看文章的同時,不要忘記看回復。 

不過針對Quake Wang的例子,我也想做一些補充。它的例子中,主要講述了Struts2中如何去做java.utils.Date的自動類型轉(zhuǎn)化,也正如后面回復中有人提到: 
wolfsquare 寫道
如果我在界面上有兩種格式的日期怎么辦? 
例如一種短格式: SimpleDateFormat("yyyy-mm-dd"),一種長格式SimpleDateFormat("yyyy-mm-dd hh:MM:ss")

而Quake Wang對此是這樣解決的: 
Quake Wang 寫道
可以根據(jù)你的應用情況,看哪種方式是比較常見的轉(zhuǎn)換規(guī)則,那么把這個規(guī)則定成Application-wide conversion rules: 
Java代碼 
  1. 在classpath root下面寫一個xwork-conversion.properties:  
  2. java.util.Date=com.javaeye.core.webwork.converter.DateConverter   

另外的一個轉(zhuǎn)換,可以寫成Class-specific conversion rules : 
otherDate=com.javaeye.core.webwork.converter.OtherDateConverter


我在這里提供一個我在實際項目中采用的方式: 

Java代碼 
  1. public class DateConverter extends DefaultTypeConverter {  
  2.   
  3.     private static final Log logger = LogFactory.getLog(DateConverter.class);  
  4.   
  5.     private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";  
  6.   
  7.     private static final String DATE_PATTERN = "yyyy-MM-dd";  
  8.       
  9.     private static final String MONTH_PATTERN = "yyyy-MM";  
  10.   
  11.     /** 
  12.      * Convert value between types 
  13.      */  
  14.     public Object convertValue(Map ognlContext, Object value, Class toType) {  
  15.         Object result = null;  
  16.         if (toType == Date.class) {  
  17.             result = doConvertToDate(value);  
  18.         } else if (toType == String.class) {  
  19.             result = doConvertToString(value);  
  20.         }  
  21.         return result;  
  22.     }  
  23.   
  24.     /** 
  25.      * Convert String to Date 
  26.      *  
  27.      * @param value 
  28.      * @return 
  29.      */  
  30.     private Date doConvertToDate(Object value) {  
  31.         Date result = null;  
  32.   
  33.         if (value instanceof String) {  
  34.   
  35.             // TODO add date converter parse order here  
  36.             result = DateUtils.parseDate((String) value, new String[] { DATE_PATTERN, DATETIME_PATTERN, MONTH_PATTERN });  
  37.   
  38.             // all patterns failed, try a milliseconds constructor  
  39.             if (result == null && StringUtils.isNotEmpty((String)value)) {  
  40.   
  41.                 try {  
  42.                     result = new Date(new Long((String) value).longValue());  
  43.                 } catch (Exception e) {  
  44.                     logger.error("Converting from milliseconds to Date fails!");  
  45.                     e.printStackTrace();  
  46.                 }  
  47.   
  48.             }  
  49.   
  50.         } else if (value instanceof Object[]) {  
  51.             // let's try to convert the first element only  
  52.             Object[] array = (Object[]) value;  
  53.   
  54.             if ((array != null) && (array.length >= 1)) {  
  55.                 value = array[0];  
  56.                 result = doConvertToDate(value);  
  57.             }  
  58.   
  59.         } else if (Date.class.isAssignableFrom(value.getClass())) {  
  60.             result = (Date) value;  
  61.         }  
  62.         return result;  
  63.     }  
  64.   
  65.     /** 
  66.      * Convert Date to String 
  67.      *  
  68.      * @param value 
  69.      * @return 
  70.      */  
  71.     private String doConvertToString(Object value) {  
  72.         SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATETIME_PATTERN);  
  73.         String result = null;  
  74.         if (value instanceof Date) {  
  75.             result = simpleDateFormat.format(value);  
  76.         }  
  77.         return result;  
  78.     }  
  79. }  


在我采用的方式中,依然采用Application-wide conversion rules,只是在自定義的Converter中,根據(jù)不同的日期形式進行逐個匹配,找到第一個匹配的日期類型進行轉(zhuǎn)化。當然,這是一種投機取巧的辦法,不過比較實用,適用于項目中不太使用國際化,日期的形式不太復雜的情況。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多