有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用生成的类和Jackson将JSON数据流读取到对象

我已经根据一个招摇过市的定义生成了类。共有4个不同的类,其中一个字段是公共的op(没有类层次结构,每个类中都会复制该字段)

我想根据op字段的值,将JSON数据流反序列化为4个不同类中的一个

例如:

{"op": "typeA", ...} -> generates TypeA
{"op": "typeB", ...} -> generates TypeB

我想用杰克逊来做这个。我遇到的问题是,我找到的所有示例都假设您能够修改原始类,以便创建类层次结构来解决问题。然而,我的问题是,如何在不修改原始类的情况下解决这个问题

最初的示例假定一个层次结构,并按如下方式执行:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "op",
        visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ConnectionMessage.class, name = "connection"),
        @JsonSubTypes.Type(value = StatusMessage.class, name = "status"),
        @JsonSubTypes.Type(value = MarketChangeMessage.class, name = "mcm"),
        @JsonSubTypes.Type(value = OrderChangeMessage.class, name = "ocm"),
})
public interface MixInResponseMessage {

}

共 (1) 个答案

  1. # 1 楼答案

    这可以通过带有switch-case语句的自定义反序列化程序来完成,以根据“op”字段的值解析正确的类型:

    class OpDeserializer extends JsonDeserializer {
        private final ObjectMapper mapper = new ObjectMapper();
    
        @Override
        public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            final JsonNode node = jsonParser.readValueAsTree();
            final String op = node.get("op").asText();
            switch (op) {
                case "typeA": return mapper.treeToValue(node, TypeA.class);
                case "typeB": return mapper.treeToValue(node, TypeB.class);
                default: return mapper.treeToValue(node, Object.class);
            }
        }
    }
    

    请注意ObjectMapper字段如何用于将TreeNode转换为所需类型的对象

    这不需要TypeATypeB等具有除Object之外的任何其他公共父级

    有必要将此反序列化器指定为用于每个带有"op"字段的JSON元素。我通过解析此类进行了测试:

    class Ops {
        @JsonDeserialize(contentUsing = OpDeserializer.class)
        Object[] ops;
    }