4

I am trying to serialize a HashMap from Objects to Strings, but the specific Object has a reference to the current class leading to an infinite recursion, which doesn't seem to be solved with the usual JsonIdentifyInfo annotation. Here's an example:

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");
    }

}

Here's the serializer/deserializer for the key:

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);
}
}

If I switch the map to HashMap (String,Object) it works but I cannot change the original mapping. Any ideas?

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 回答