杰克逊嵌套的反序列化器调用另一个

时间:2015-09-28 07:36:19

标签: java json serialization jackson

我的课程如下:

class A {
    private String z;
    private String y;
    private List<B> bs;
}

class B {
    private String x;
}

为了序列化A,我创建了两个序列化程序,一个用于A,另一个用于B

public class ASerializer extends JsonSerializer<A> {

@Override
public void serialize(A value, JsonGenerator gen,
        SerializerProvider serializers) throws IOException,
        JsonProcessingException {

    gen.writeStartObject();
    gen.writeStringField("z", value.getZ());
    gen.writeStringField("y", value.getY());

    gen.writeFieldName("bs");
    gen.writeStartArray(value.getBs().size());
    for (B b : value.getBs())
        gen.writeObject(b);
    gen.writeEndArray();

    gen.writeEndObject();  
}

public class ASerializer extends JsonSerializer<A>
{
@Override
public void serialize(B value, JsonGenerator gen,
        SerializerProvider serializers) throws IOException,
        JsonProcessingException {

    gen.writeStartObject();
    gen.writeStringField("x", value.getX());

    gen.writeEndObject();  
}

因此,BSerializer.serialize()调用ASerializer.serialize()时会自动调用gen.writeObject(b)

我试图对序列化A对象做同样的事情。 所以,我有两个序列号,一个用于A,另一个用于B.问题是我不知道我怎么能自动将杰克逊电话设置为BDeserializer ADeserializer内的@Override public A deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { A a = null; JsonNode node = p.getCodec().readTree(p); String z = node.get("z").asText(); String y = node.get("y").asText(); List<B> bs = node.get("bs") //.asListofB //...

public class ADeserializer扩展了JsonDeserializer {

A

问题是,如何从另一个人那里打电话给deseriazer?

注意: B(TOP(VP(VB Shutdown) (NP(DT all) (JJ active) (NNS devices)))) 是第三方类。所以我无法注释这些。

1 个答案:

答案 0 :(得分:0)

即使您不能直接注释这些类,也可以编写“mixin”注释类。这些类只存在用于保存注释,然后应用,就像它们在其他类上一样。例如:

public abstract class AMixin {
    @JsonProperty public abstract String getZ();
    @JsonProperty public abstract String getY();
    @JsonProperty public abstract List<B> getBs();
}

配置mixin:

mapper.addMixInAnnotations(A.class, AMixin.class);

如果你沿着基于JsonNode表示(btw extend StdNodeBasedDeserializer)编写反序列化器的路线走下去,那么你会遇到反序列化器通常在流上而不是树节点上工作的问题。现在,任何树节点都可以作为流遍历:因此可以采用node.get("bs"),调用traverse(),从而得到一个JsonParser,您可以将其传递给反序列化器。当然,如果该反序列化器最终将流转换回树节点,那就有点浪费......

我最终创建了一些封装它的东西(并且如果下一个反序列化器本身是StdNodeBasedDeserializer并且避免遍历,则采用快捷方式),但我现在还没有把它交给我。恕我直言生产mixin类让Jackson建立序列化器/反序列化器(保持同步!)是一种更好的方法。