2

次のように LinkedHashMap データをシリアライズおよびデシリアライズしようとしました。

LinkedHashMap<String, Object> o = new LinkedHashMap<String, Object>();
o.put("1", "a");
o.put("2", "b");
o.put("3", "c");
o.put("4", new BigDecimal("9999999999999999999999.00999999999999999999999"));

String serialize = new JSONSerializer().deepSerialize(o);
System.out.println("serialize" + serialize);

LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>().deserialize(serialize, LinkedHashMap.class);
System.out.println("deserialize:" + deserialize);

そして私は ClassCastException を取得します:

serialize{"1":"a","2":"b","3":"c","4":9999999999999999999999.00999999999999999999999}
Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap
    at com.JSONUtil.main(JSONUtil.java:161)

したがって、次のように逆シリアル化するときに、少し異なるアプローチを試みました。

HashMap deserialize = new JSONDeserializer<HashMap>().deserialize(serialize, HashMap.class);
System.out.println("deserialize:" + deserialize);

今回は結果が得られますが、マップは順不同です(現在HashMapを使用しているためだと思います)。また、元の形式のように BigDecimal 値が表示されません。

deserialize:{3=c, 2=b, 1=a, 4=1.0E22}

FlexJSON にはソートされたマップに問題があるようです。これは、以下の例のように「クラス」エントリを配置する方法がないためだと思います。

"class":"ch.qos.logback.classic.Logger","debugEnabled":true,"errorEnabled":true,"infoEnabled":true}

または、これを行う別の方法があるかもしれません。誰でも助けてもらえますか?ありがとうございました


chubbsondubs の提案に従って ObjectFactory を導入した後:

LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>()
.use(LinkedHashMap.class, new ObjectFactory() {
public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) {
    System.out.println("mymap:"value);
}
}).deserialize(serialize, LinkedHashMap.class);

値オブジェクトには HashMap タイプがあり、次のように出力されます。

mymap:{3=c, 2=b, 1=a, 4=flexjson.JsonNumber@104fc23}
4

1 に答える 1

2

デフォルトでは、入力情報のないオブジェクトは、ドキュメントで説明されている HashMap として解釈されます。HashMap を使用しないのは、埋め込みクラス プロパティ (機能しますが、ネットワーク上では安全ではありません)、オブジェクト パスで指定された型からオブジェクトの型を判別できる場合、または逆シリアル化する場合です。型を解釈できる型付きオブジェクト。

したがって、標準コレクションのようなクラスは、実行時に単純なオブジェクト参照であるため、Flexjson が Collection/Map クラスから含まれている型を推測できる方法はありません。数値は、JSON が型情報を指定しないもう 1 つの領域です。数値を Java にマップする場合、バイト、ショート、int、ロング、BigInteger、float、double、BigDecimal のいずれかになります。入力情報が指定されていない場合、Flexjson は呼び出しを行う必要があります。デフォルトでは、小数の場合は double を使用し、整数の場合は long を使用します。あなたの場合、それは倍精度であるため、指数形式で表示されます。

必要なタイプを指定する必要があります。型指定されたオブジェクトを使用するか、オブジェクト パスで型を構成するか、カスタム ObjectFactory を作成します。型付きオブジェクトを作成できない限り、ObjectFactory が唯一の選択肢だと思います。その理由は、マップ内の値の型が異なるためです。一部のエントリは文字列で、別のエントリは BigDecimal です。そのため、LinkedHashMap をインスタンス化し、すべてのキーをソースからターゲットにコピーして、ソースの値が JsonNumber の場合はそれらを BigDecimal に変換することを認識している特別な ObjectFactory が必要です。

于 2013-07-08T20:47:37.147 に答える