我想为我们的REST API实现一个自定义的反序列化器,它不仅被Java应用程序使用。因此,我不想让Jackson将类型信息放入序列化的JSON中。
我目前正在努力反序列化<code>CollectionExpand</code>,因为它包含特定<code>ResourceModel</code>的<code>数据</code>列表。
public class EntityModel<R extends ResourceModel> implements Serializable {
private R data;
private List<ResourceLink> links;
private List<CollectionExpand> expands;
}
public class CollectionExpand {
private String name;
// Resource Model is an interface
private Collection<ResourceModel> data;
}
< code>ResourceModel是一个接口,每个< code>CollectionExpand包含每个< code>name的一种类型的< code>ResourceModel的集合。
例如,json 输出可能如下所示。
{
"data": {},
"links": [],
"expand": [
{
"name": "photos",
"data": [
{
"id": 12,
"name": "hello.jpg"
},
{
"id": 12,
"name": "hello.jpg"
}
]
},
{
"name": "persons",
"data": [
{
"id": 783378,
"name": "Peter",
"age": 12
},
{
"id": 273872,
"name": "Maria",
"age": 77
}
]
}
]
}
如您所见,每个名称都包含相同类型的资源模型。< code>photos包含< code > photosourcemodel ,而< code>person包含< code>PersonResourceModel。
我开始实现我定制的Jackson反序列化器
public class CollectionExpandDeserializer extends StdDeserializer<CollectionExpand> {
public CollectionExpandDeserializer() {
super(CollectionExpand.class);
}
@Override
public CollectionExpand deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
CollectionExpand collectionExpand = new CollectionExpand();
if (Objects.equals(p.nextFieldName(), "name")) {
collectionExpand.setName(p.nextTextValue());
}
if (Objects.equals(p.nextFieldName(), "data")) {
// depending on the field name I would like to delegate the deserialization to a specific type.
if (name.equals("photos") {
// how to do this?
collectionExpand.setData(/* deserialize to a list of PhotoResource */);
}
}
return collectionExpand;
}
我目前陷入了如何委托告诉杰克逊将其反序列化为照片资源
列表的问题。
一般来说,这是正确的方法还是有另一种方法可以做到这一点(在序列化时无需将任何杰克逊元数据放入 JSON 中)?
我最终实现了我的自定义反序列化程序,如下所示
@Override
public CollectionExpand deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
JsonNode node = ctx.readTree(p);
CollectionExpand collectionExpand = new CollectionExpand();
collectionExpand.setName(node.get("name").asText());
ArrayNode data = node.withArray("data");
Iterator<JsonNode> iterator = data.iterator();
while (iterator.hasNext()) {
Class<? extends ResourceModel> aClass = resolveClass(collectionExpand.getName());
if (aClass != null) {
JsonNode jsonNode = iterator.next();
collectionExpand.getData().add(p.getCodec().treeToValue(jsonNode, aClass));
}
}
return collectionExpand;
}
private Class<? extends ResourceModel> resolveClass(String name) {
if ("contents".equals(name)) {
return ContentsGetResourceModel.class;
} else if ("tags".equals(name)) {
return TagsGetResourceModel.class;
} else {
return null;
}
}
我花了一段时间来理解如何将JsonNode
/TreeNode
反序列化为特定类型。最后我了解到这基本上可以通过使用解析器编解码器来完成。
PhotoResource photoResource = p.getCodec().treeToValue(jsonNode, PhotoResource.class);
我对Jackson和类型层次结构有以下问题。我正在序列化一个类SubA,该类将扩展为一个字符串,然后尝试将其反序列化回来。当然,在编译时,系统不知道它是基还是SubA,因此我希望它是基,如果它是SubA,则会在编译后执行一些其他操作。 我的基本类看起来像: ...和一个派生自的类: ... 我试图执行以下代码: String是: 但我一次又一次地犯同样的错误。映射器现在知道如何处理另一个类参数-它
I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器
问题内容: 如果我有这样的类结构: 还有另一种反序列化的方法吗?在父类上使用此注释: 我不想强迫我的API的客户包括反序列化一个子类。 杰克逊不是使用,而是提供了一种方法来注释子类并通过唯一属性将其与其他子类区分开来?在上面的示例中,这类似于“如果JSON对象将其反序列化为,如果它将其反序列化为”。 问题答案: 感觉像是应该使用的东西,但是我在文档中进行了选择,可以提供的任何属性似乎都不符合您所描
我有以下几个类,我想使用Jackson反序列化JSON字符串。 PushNotificationMessage.java 设备信息。Java语言 IOSDeviceInfo。Java语言 WebDeviceInfo.java 我有以下要反序列化的JSON内容: 我只需使用ObjectMapper来尝试执行反序列化。 当我这样做时,我得到: com.fasterxml.jackson.databin
我看过jackson反序列化@JsonTypeInfo的一个例子,那就是: 我试过了,效果很好。现在的问题是,在示例类中,Cat和Dog是从Animal中引用的,我想避免这种情况。有没有一种方法可以将类型绑定从类动物中移除,并且仍然进行反序列化工作?谢谢
我想反序列化以下XML(缩短示例): 到目前为止,我想出的代码: 但这种方法存在几个问题: > @JacksonXmlProperty t(localName="subject")始终为空,因为我将其用于类型信息。为什么?,或者如何绕过它? 还是这种方法已经错了? 最后是我使用的周围类: