JavaとC#間のjson時間フォーマットの相互転送の完璧な解決策

3569 ワード

[size=medium]は簡単で便利なデータ伝送方式として機能し,JSONはXMLに代わる事実基準となっている.しかしJSONでは,時間(DateTime,Timestamp,Dateなど)フォーマットがうまく統一されておらず,プラットフォーム間シーケンス化/逆シーケンス化が必要な場合に多くのトラブルが発生する.著者らは試行錯誤を繰り返し,C#とJavaのJSONによる時間伝送の困難を解決した.
C#解析Java/Javascript生成のJSONは難しくないが、Java解析C#生成のJSONは困難である.以下、この問題について重点的に紹介します.
[b]1、基本状況[/b]
Java:
Java側でよく使われるjson-libライブラリではTimestampタイプの逆シーケンス化はサポートされていません(データ型を変更できると言われていますが、申し訳ありませんが、履歴コードは変更したいのではなく変更できるものが多いです).Jacksonとgsonはミリ秒数形式の逆シーケンス化をサポートすることができる.Javaのシーケンス化行為は比較的簡単で、常識に合っていると言える.
C#エンド:
デフォルトでは、C#の時間は「/Date(1294499956278+0800)/」という形式にフォーマットされます.明らかに、この形式は処理しにくい.
幸いなことに、JsonConvertサードパーティライブラリには2つの追加フォーマットが用意されています.
a. IsoDateTimeConverter[/size]

IsoDateTimeConverter convert = new IsoDateTimeConverter();
string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);

[size=medium]この方法でフォーマットした結果は
"2013-05-31T15:14:13.1294788+08:00"
b. JavaScriptDateTimeConverter[/size]

JavaScriptDateTimeConverter convert = new JavaScriptDateTimeConverter();
string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);

[size=medium]この方法でフォーマットした結果は
new Date(1369984667554)
しかし、それでもC#の3つのフォーマットはJavaと同じではなく、正しくドッキングできません.
[b]2、解決策[/b]
[color=red]試験を繰り返した結果、両端に「yyyy-MM-dd HH:mm:ss.SSS」の形式で伝送することが決定され、これもこれまで試験に成功した唯一の方法である.[/color]
Java側:[/size]

JsonGenerator jsonGenerator = null;
ObjectMapper objectMapper = null;

objectMapper = new ObjectMapper();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
objectMapper.getDeserializationConfig().setDateFormat(formatter);

try {
jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(System.out, JsonEncoding.UTF8);
} catch (IOException e) {
e.printStackTrace();
}
String json = "{\"name\":\"YK\",\"value\":3,\"tm\":\"2013-05-31 02:53:20.123\"}";
try {
MyBean b = objectMapper.readValue(json, MyBean.class);
System.out.println(b.getTm());
} catch (Exception e) {
e.printStackTrace();
}

IsoDateTimeConverter convert = new IsoDateTimeConverter();
convert.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
string ret = JsonConvert.SerializeObject(bean, Formatting.None, convert);

[size=medium]文で使用するMyBeanタイプ定義:[/size]

import java.sql.Timestamp;

public class MyBean {

private String name;
private String value;
private Timestamp tm;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Timestamp getTm() {
return tm;
}
public void setTm(Timestamp tm) {
this.tm = tm;
}

}

[size=medium]後記:
私は比較的古い.net 2.0を使っていますが、C#のJSON変換は高バージョンで原生サポートを提供しています.この問題は4.0/4.5のFrameworkでもっと良い解決策があるかどうか、皆さんのフィードバックを期待しています.
また、C#がJavaにデータを渡す場合、生成したJsonには余分なフィールドが含まれていることが多く、サーバ側の解析でエラーが発生する可能性があります.解決策は以下の通りです.

objectMapper.getDeserializationConfig().set( org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

[size=medium]elgsとbypassccの本稿のサポートに感謝します.[/size]