0

私は現在、Jacksonを使用してオブジェクトをJSON文字列に変換しようとしていますが、これは簡単に実行できました

public byte[] toJSON(Object obj) throws IOException {
        ObjectMapper map = new ObjectMapper();
        return map.writeValueAsString(obj).getBytes();
    }

問題が発生するのは、バイト配列を取得してオブジェクトに変換するときです。現在私は持っています:

public Object toObject(byte[] bytes) throws IOException, ClassNotFoundException {
    ObjectMapper map = new ObjectMapper();
    return (Object)map.readValue(bytes, Object.class);
}

オブジェクトを JSON 文字列に正常に変換しましたが、toObject メソッドから返されたオブジェクトは、最初に JSON 文字列に変換されたオブジェクトではなく、常に LinkedHashMap です。

問題をうまく伝えられなかった場合は申し訳ありませんが、簡単に要約してみてください。コードで次のことができるようにしたい:

MyClass someObject = new MyClass();
String json = toJSON(someObject);
Object tempObject = toObject(json);
MyClass sameObject = (MyClass) tempObject;

このコードは現在、次をスローします。

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.MyClass

この問題に関するヘルプをいただければ幸いです。

4

2 に答える 2

1

を要求しているObjectので、Jackson は、Object作成できることがわかっているものを作成します: a Map. JSON 配列は などになりListます。

必要な場合MyClassは明示的にリクエストするか、汎用のシリアライゼーション/デシリアライゼーションが必要な場合は、@csd で提案されているように、型識別子を含める必要があります。

于 2012-07-11T17:48:24.877 に答える
0

まず、なぜ対処する必要があるのか​​、少し混乱してbyte[]います。 オブジェクトの JSON 表現にobjectMapper.writeVaueAsString(obj)完全に適しています。Stringに変換する必要がある場合は、 を呼び出す前にbyte[]に戻す必要があります。StringreadValue

Stringしかし、今はそれを脇に置いて、JSONを含むものがあると仮定しましょう。デフォルトでは、Jackson は (JSON だけを見て) を呼び出したときにどの Java クラスをインスタンス化するかを知るほど賢くありませんreadValue。あなたの例では、 を渡しますがObject.class、Java のすべてのオブジェクトは から拡張されるため、Jackson にとってはあまり役に立ちませんObject。したがって、その場合、組み込みのデフォルトが選択されます。これは、JSON にリストされているキーと値を使用してa Map(特に a ) を構築することです。LinkedHashMap

あるコメンターが指摘したように、Jackson にヒントを与えMyClass.classて、2 番目のパラメーターとしてreadValue(の代わりにObject.class) に渡すことができます。これを行った場合、JSON はMyClassの先頭に のインスタンスを作成しますreadValue。そしてfoo: 43、JSON で " " のようなものを見つけると、フィールドまたはセッター (public int foo;またはpublic void setFoo(int f))を見つけて、MyClassそれに応じて値を設定しようとします。

オブジェクトのタイプ (つまり、 の 2 番目のパラメーターとして渡す値) が事前にわからない場合は、readValue他のオプションがあります。この例の 1 つは、class作成する Java オブジェクトのタイプのヒントとして Jackson が使用するプロパティが JSON オブジェクトにあることを要求することです。そのコードは次のようになります。

// This annotation tells Jackson to include the class name as
// a "class" property when *writing* JSON.
@JsonTypeInfo(include=As.PROPERTY, use=Id.CLASS, property="class")
public class MyClass {
    public int foo;
}

これにより、JSON は次のようになります。

{ "class":"MyClass", foo:0 }

次に、オブジェクトを読み取るコードで、次のようにします。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enableDefaultTypingAsProperty(DefaultTyping.JAVA_LANG_OBJECT, "class");
// Note Object.class as second parameter.  Jackson will find the "class"
// property in the JSON and use it to determine which class to make.
MyClass foo = (MyClass) objectMapper.readValue(jsonString, Object.class);
于 2012-07-10T18:00:38.707 に答える