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


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

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

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

1、基本情況 

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相同的,仍然無法正確對接。 

2、解決方案 

經過反復測試,最終決定兩端均使用 "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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM