使用Jackson反序列化派生类

时间:2018-05-15 08:51:47

标签: java inheritance jackson deserialization

我有两个自动生成的类,如下所示:

public class DataMonitoringClauseType extends ClauseType {
}

public class ClauseType {
}

由于这些类是自动生成的,因此我无法为其定义其他注释,例如JsonSubType

我有第三个对象,其中包含ClauseTypes列表,如下所示:

public class RootClass {
    List<ClauseType> clauses;
}

鉴于序列化RootClass,有没有办法反序列化RootClass实例,以便在DataMonitoringClauseType列表中包含clauses个实例?

我已经尝试按如下方式注册派生类,但没有成功:

ObjectMapper mapper = new ObjectMapper();
mapper.registerSubtypes(DataMonitoringClauseType.class);

请注意,序列化内容作为输入传递给服务器。因此,我没有机会在序列化内容中包含类型信息。

2 个答案:

答案 0 :(得分:0)

对于Jackson,您可以按照

的顺序为ClauseType定义自定义反序列化器
class ClauseTypeDeserializer extends StdDeserializer<DataMonitoringClauseType> {

    @Override
    public DataMonitoringClauseType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        // get data, e.g.: data = jp.getCodec().readTree(jp).toString().getBytes();
        // construct result:
        return new DataMonitoringClauseType(data)
    }
}

您可以使其更通用,声明返回ClauseType,然后根据数据决定返回哪个实例。无论哪种方式,使用以下代码ObjectMapper注册:

ObjectMapper mapper = new ObjectMapper()
  .registerModule(new SimpleModule()
    .addDeserializer(ClauseType.class, new ClauseTypeDeserializer()));

如果您对Gson感兴趣,解决方案非常相似:

class ClauseTypeDeserializer implements JsonDeserializer<ClauseType> {

    @Override
    public ClauseType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // get data, e.g.: data = jpson.toString().getBytes();
        // construct result:
        return new DataMonitoringClauseType(data)
    }
}

并将其注册到GsonBuilder

Gson gson = new GsonBuilder()
  .registerTypeAdapter(ClauseType.class, new ClauseTypeDeserializer())
  .build();

答案 1 :(得分:0)

不需要使用自定义解串器 无需自定义反序列化器或Gson。杰克逊提供了几种方式。

首先:因为你不能直接修改类并不意味着你不能使用Jackson注释:这是“混合”注释的确切用例。有关如何使用混合的示例,请参阅https://dzone.com/articles/jackson-mix-in-annotations,因此您可以使用等效的

@JsonDeserialize(as=DataMonitoringClauseType.class)
public class ClauseType { .... }

或者您也可以注册实现类型(您注册子类型的尝试适用于多态子类型,其中使用了类型ID - 但我认为这不是您想要的)。 这是使用Module接口,方法“addAbstractTypeMapping()”

完成的

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/module/SimpleModule.html#addAbstractTypeMapping-java.lang.Class-java.lang.Class-