4

オブジェクトから文字列に HashMap をシリアル化しようとしていますが、特定のオブジェクトに現在のクラスへの参照があり、無限再帰につながるため、通常の JsonIdentifyInfo アノテーションでは解決できないようです。次に例を示します。

public class CircularKey {

    public void start() throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        Cat cat = new Cat();

        // Encode
        String json = mapper.writeValueAsString(cat);
        System.out.println(json);

        // Decode
        Cat cat2 = mapper.readValue(json, Cat.class);
        System.out.println(mapper.writeValueAsString(cat2));
    }
}

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
class Mouse {
    int id;

    @JsonProperty
    Cat cat;
}

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
class Cat {
    int id;

    @JsonSerialize(keyUsing = MouseMapKeySerializer.class)
    @JsonDeserialize(keyUsing = MouseMapKeyDeserializer.class)
    @JsonProperty
    HashMap<Mouse, String> status = new HashMap<Mouse, String>();

    public Cat() {
        Mouse m = new Mouse();
        m.cat = this;
        status.put(m, "mike");
    }

}

キーのシリアライザー/デシリアライザーは次のとおりです。

class MouseMapKeySerializer extends JsonSerializer<Mouse> {
static ObjectMapper mapper = new ObjectMapper();

@Override
public void serialize(Mouse value, JsonGenerator generator,
        SerializerProvider provider) throws IOException,
        JsonProcessingException {
    String json = mapper.writeValueAsString(value);
    generator.writeFieldName(json);
}
}

class MouseMapKeyDeserializer extends KeyDeserializer {
static ObjectMapper mapper = new ObjectMapper();

@Override
public Mouse deserializeKey(String c, DeserializationContext ctx)
        throws IOException, JsonProcessingException {
    return mapper.readValue(c, Mouse.class);
}
}

マップを HashMap (String,Object) に切り替えると機能しますが、元のマッピングを変更できません。何か案は?

4

1 に答える 1

1

http://jackson-users.ning.com/forum/topics/serializing-hashmap-with-object-key-and-recursionで答えを見つけたようです。次の理由により、これは不可能のようです。

複雑なキーは扱いが難しく、私がこれまで検討したユース ケースではありません。繰り返しになりますが、標準コンポーネントの使用を特に妨げるものは何もありません。主な関心事は、JSON よりも制限があることだけでした (文字列値である必要があり、JsonParser/JsonGenerator はキーを異なるトークンとして公開します)。オブジェクト キーのポリモーフィック タイプまたはオブジェクト ID の明示的なサポートはありません。標準のシリアライザー/デシリアライザーは、ほとんどの場合、文字列との間で簡単かつ確実に変換できる比較的単純な型用です。数字、日付、UUID。

したがって、モジュール設計 (TypeSerializer/JsonSerializer の分離) が理にかなっている値ハンドラーとは異なり、すべての側面を処理するカスタム (デ) シリアライザーを用意する必要があると思います。既存の値 (デ) シリアライザー、型 (デ) シリアライザーのコードを使用できるはずですが、クラス自体は使用できません。

あなたのユースケースは興味深いように聞こえますが、良くも悪くも、限界をかなり押し上げています。:-)

于 2015-12-25T02:16:48.957 に答える