1

我正在使用 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:无法从>START_OBJECT 标记中反序列化 java.util.ArrayList 的实例 [来源:N/A;行:-1,列:-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;
}

抱歉,如果我上面的解释不是那么清楚。我认为杰克逊必须有一种方法来实现这一点,但就是想不通。如果有人有任何想法或可以指出我正确的方向,将不胜感激。

谢谢, 真皮

4

0 回答 0