我正在使用Jackson将JSON字符串反序列化为对象。我有一个类似于下面的对象
@Data
public class Party {
protected String partyType;
protected List<Field> fields;
}
要反序列化此派对对象,我有一个mixin类,其工作方式如下
@JsonIgnoreProperties(ignoreUnknown = true)
abstract class PartyMixin {
@JsonCreator
PartyMixin(@JsonProperty("partyType") String partyType) {}
@JsonProperty("fields")
@JsonDeserialize(using=FieldListDeserializer.class) List<Field> fields;
private static final class FieldListDeserializer extends JsonDeserializer<List<Field>> {
public List<Field> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return DeserializationUtils.deserializeFromDataNode(jp, ctxt, "field", new TypeReference<List<Field>>() {});
}
}
}
使用deserializeFromDataNode方法,如
public static <T> T deserializeFromDataNode(JsonParser jp, DeserializationContext ctxt, String propertyName, TypeReference<T> typeReference) throws IOException, JsonProcessingException {
if (jp.hasCurrentToken() && jp.getCurrentToken().equals(JsonToken.START_OBJECT)) {
JsonNode dataNode = jp.readValueAs(JsonNode.class);
if (dataNode.has(propertyName)) {
return OBJECT_MAPPER.reader(typeReference).<T>readValue(dataNode.get(propertyName));
}
return null;
}
throw ctxt.mappingException("Expected JSON object");
}
这一切都正常,并且arrayList被反序列化为正确的正确对象列表。然而,我遇到困难的地方是在下面的场景中,我有一个派对列表,每个派对都有一个字段列表
@Data
public class Event {
protected Integer eventId;
protected List<Party> parties;
}
在这种情况下,我在上面的反序列化时遇到错误。
@JsonProperty("parties")
@JsonDeserialize(using=PartyListDeserializer.class) List<Party> parties;
private static final class PartyListDeserializer extends JsonDeserializer<List<Party>> {
public List<Party> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return DeserializationUtils.deserializeFromDataNode(jp, ctxt, "party", new TypeReference<List<Party>>() {});
}
}
错误是
java.lang.IllegalArgumentException:无法从&gt; START_OBJECT标记中反序列化java.util.ArrayList的实例 在[资料来源:N / A; line:-1,column:-1](通过引用链:
我得到了我收到错误的原因 - 当我反序列化对象数组时,它不希望其中一个嵌套对象包含数组。这就是我遇到一种整洁的可重用方式来遍历JSON并反序列化常规对象和数组对象的地方。创建泛型方法的主要障碍是如何知道嵌套数组的类型。所以在我上面的第一个数组的方法中,我把类型传递给了读者。如果我将方法更改为递归并检查节点是否为数组,那么如何从节点推断出类型和名称?
if (dataNode.has(propertyName)) {
for(JsonNode subNode: dataNode) {
if (subNode.isArray()) {
// How to know the type and name from the node to pass it in?
List<T> subActions = deserializeFromDataNode(jp, ctxt...
}
else {
T value = OBJECT_MAPPER.reader(typeReference).readValue(subNode);
actions.add(value);
}
}
return (T) actions;
}
如果我上面的解释不清楚,请道歉。我认为杰克逊必须有办法实现这一目标但却无法弄明白。如果有人有任何想法或能指出我正确的方向,那将非常感激。
谢谢, 真皮