我有两个自动生成的类,如下所示:
public class DataMonitoringClauseType extends ClauseType {
}
public class ClauseType {
}
由于类是自动生成的,因此我无法为它们定义其他注释,例如JsonSubType
。
我有第三个对象,其中包含子句类型列表,如下所示:
public class RootClass {
List<ClauseType> clauses;
}
给定一个序列化的RootClass
,有没有办法反序列化RootClass
实例,以便我在clauses
列表中有DataMonitoringClauseType
个实例?
我已经尝试注册派生类,如下所示,但没有成功:
ObjectMapper mapper = new ObjectMapper();
mapper.registerSubtypes(DataMonitoringClauseType.class);
请注意,序列化内容作为输入传递到服务器。因此,我没有机会在序列化内容中包含类型信息。
不需要使用自定义反序列化程序 无需自定义反序列化程序或 Gson。杰克逊提供了几种方法。
首先:仅仅因为你不能直接修改类并不意味着你不能使用杰克逊注解:这是"mix-in"注解的确切用例。例如,请参阅有关如何使用mix-in的 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-
对于 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();