使用Jackson序列化具有循环引用的键

4
我试图将一个HashMap从对象序列化为字符串,但是特定的对象引用了当前类导致了无限递归,通常的@JsonIdentityInfo注解似乎不能解决这个问题。下面是一个例子:
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),它可以工作,但我无法更改原始映射。有什么想法?
1个回答

1

看起来你在http://jackson-users.ning.com/forum/topics/serializing-hashmap-with-object-key-and-recursion找到了答案。这似乎是不可能的,因为:

复杂的键很棘手,这不是我曾经考虑过的用例。然而,没有什么特别防止使用标准组件;主要关注点只是JSON具有的限制(必须是字符串值,JsonParser / JsonGenerator将键公开为不同的标记)。

没有明确支持多态类型或对象id作为对象键。标准的序列化程序/反序列化程序大多是针对相对简单的类型,可以轻松可靠地转换为/从字符串;数字、日期、UUID。

所以:与值处理程序不同,其中模块化设计(分离TypeSerializer / JsonSerializer)是有意义的,我认为你需要做的是拥有自定义(反)序列化程序来处理所有方面。您应该能够使用现有值(反)序列化程序、类型(反)序列化程序中的代码,但不能使用类本身。

你的用例听起来很有趣,但好坏参半,它确实推动了很多方面的发展。 :-)


链接已经失效。 - Nick Breen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接