Java與C#間json日期格式互轉完美解決方案

轉自: http://blog.csdn.net/wilsonke/article/details/24362851java

 
做用一種簡單方便的數據傳輸方案,JSON已經成爲替代XML的事實標準。然而在JSON中,時間(DateTime,Timestamp,Date等)格式一直沒有很好地統一,當須要跨平臺序列化/反序列化時,遇到很多麻煩。做者通過反覆嘗試,解決了C#與Java經過JSON進行時間傳輸的困難。

C#解析Java/Javascript生成的JSON並不困難,但Java解析C#生成的JSON困難重重。下面就此問題重點介紹。 

一、基本狀況 

Java端: 
Java端經常使用的json-lib庫不支持Timestamp類型的反序列化(有人說能夠改數據類型啊,對不起,不少都是歷史代碼不是想改就能改的)。而Jackson與gson能支持毫秒數形式的反序列化。應該說,Java的序列化行爲是比較簡單、符合常理的。

C#端: 
默認狀況下,C#的時間將被格式化爲 "/Date(1294499956278+0800)/" 這種形式。很顯然,這種形式難以處理。 

幸虧,JsonConvert第三方庫提供了兩種額外的格式: 

a. IsoDateTimeConverter 

C#代碼  複製代碼  收藏代碼
  1. IsoDateTimeConverter convert = new IsoDateTimeConverter();  
  2. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  
[C#]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. IsoDateTimeConverter convert = new IsoDateTimeConverter();  
  2. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  


使用這種方式格式化後的結果是 
"2013-05-31T15:14:13.1294788+08:00" 

b. JavaScriptDateTimeConverter 

C#代碼  複製代碼  收藏代碼
  1. JavaScriptDateTimeConverter convert = new JavaScriptDateTimeConverter();  
  2. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  
[C#]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. JavaScriptDateTimeConverter convert = new JavaScriptDateTimeConverter();  
  2. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  


使用這種方式格式化後的結果是 
new Date(1369984667554) 

然而,即便如此,C#的三種格式沒有一種是與Java相同的,仍然沒法正確對接。 

二、解決方案 

通過反覆測試,最終決定兩端均使用 "yyyy-MM-dd HH:mm:ss.SSS" 的格式進行傳輸,這也是到目前爲止測試成功的惟一一種方案。

Java端: 

Java代碼  複製代碼  收藏代碼
  1. JsonGenerator jsonGenerator = null;  
  2. ObjectMapper objectMapper = null;  
  3.           
  4. objectMapper = new ObjectMapper();  
  5. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");   
  6. objectMapper.getDeserializationConfig().setDateFormat(formatter);  
  7.           
  8. try {  
  9.     jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(System.out, JsonEncoding.UTF8);  
  10. catch (IOException e) {  
  11.     e.printStackTrace();  
  12. }  
  13. String json = "{\"name\":\"YK\",\"value\":3,\"tm\":\"2013-05-31 02:53:20.123\"}";  
  14. try {  
  15.     MyBean b = objectMapper.readValue(json, MyBean.class);  
  16.     System.out.println(b.getTm());  
  17. catch (Exception e) {  
  18.     e.printStackTrace();  
  19. }  
[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. JsonGenerator jsonGenerator = null;  
  2. ObjectMapper objectMapper = null;  
  3.           
  4. objectMapper = new ObjectMapper();  
  5. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");   
  6. objectMapper.getDeserializationConfig().setDateFormat(formatter);  
  7.           
  8. try {  
  9.     jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(System.out, JsonEncoding.UTF8);  
  10. catch (IOException e) {  
  11.     e.printStackTrace();  
  12. }  
  13. String json = "{\"name\":\"YK\",\"value\":3,\"tm\":\"2013-05-31 02:53:20.123\"}";  
  14. try {  
  15.     MyBean b = objectMapper.readValue(json, MyBean.class);  
  16.     System.out.println(b.getTm());  
  17. catch (Exception e) {  
  18.     e.printStackTrace();  
  19. }  


C#代碼  複製代碼  收藏代碼
  1. IsoDateTimeConverter convert = new IsoDateTimeConverter();  
  2. convert.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";  
  3. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  
[C#]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. IsoDateTimeConverter convert = new IsoDateTimeConverter();  
  2. convert.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";  
  3. string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);  


文中用的到MyBean類型定義: 
Java代碼  複製代碼  收藏代碼
  1. import java.sql.Timestamp;  
  2.   
  3. public class MyBean {  
  4.   
  5.     private String name;  
  6.     private String value;  
  7.     private Timestamp tm;  
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.     public String getValue() {  
  15.         return value;  
  16.     }  
  17.     public void setValue(String value) {  
  18.         this.value = value;  
  19.     }  
  20.     public Timestamp getTm() {  
  21.         return tm;  
  22.     }  
  23.     public void setTm(Timestamp tm) {  
  24.         this.tm = tm;  
  25.     }  
  26.       
  27. }  
[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. import java.sql.Timestamp;  
  2.   
  3. public class MyBean {  
  4.   
  5.     private String name;  
  6.     private String value;  
  7.     private Timestamp tm;  
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.     public String getValue() {  
  15.         return value;  
  16.     }  
  17.     public void setValue(String value) {  
  18.         this.value = value;  
  19.     }  
  20.     public Timestamp getTm() {  
  21.         return tm;  
  22.     }  
  23.     public void setTm(Timestamp tm) {  
  24.         this.tm = tm;  
  25.     }  
  26.       
  27. }  


後記: 

我使用的是比較老的.net 2.0,而C#的JSON轉換在高版本中是提供原生支持的,此問題在4.0/4.5的Framework中是否有更好的解決方案,期待你們反饋。

另外,C#向Java傳遞數據時,其生成的Json中每每包含多餘的字段,在服務器端解析時可能報錯,解決方法以下: 
出處:http://cnblogs.com/daishuguang
相關文章
相關標籤/搜索