【问题标题】:Jackson Deserialize to POJO Based On Object PropertiesJackson 基于对象属性反序列化为 POJO
【发布时间】:2013-04-05 14:31:27
【问题描述】:

是否可以根据 JSON 的内容使用 Jackson 将 JSON 反序列化为两种类型之一?

例如,我有以下 Java(技术上是 Groovy,但这并不重要)接口和类:

interface Id {
    Thing toThing() 
}

class NaturalId implements Id {

    final String packageId

    final String thingId

    Thing toThing() {
        new PackageIdentifiedThing(packageId, thingId)
    }         
}

class AlternateId implements Id {

    final String key

    Thing toThing() {
        new AlternatelyIdentifiedThing(key)
    }
}

我将收到的 JSON 将如下所示:

这个 JSON 应该映射到 NaturalId {"packageId": "SomePackage", "thingId": "SomeEntity"}

这个 JSON 应该映射到 AlternateId {"key": "SomeUniqueKey"}

有谁知道我如何在不包括类型 ID 的情况下使用 Jackson 2.x 完成此任务?

【问题讨论】:

    标签: java json jaxb jackson


    【解决方案1】:

    这是仅有的两个实现Id 的类吗?如果是这样,您可以编写一个IdDeserializer 类并将@JsonDeserialize(using = IdDeserializer.class) 放在Id 接口上,反序列化器将查看JSON 并确定要反序列化到哪个对象。

    编辑:JsonParser 正在流式传输,所以它应该看起来像这样:

    public Id deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        ObjectNode node = jp.readValueAsTree();
        Class<? extends Id> concreteType = determineConcreteType(node); //Implement 
        return jp.getCodec().treeToValue(node, concreteType);
    }
    

    【讨论】:

    • 目前;只有这两个。在不久的将来可能会有三分之一,但我预计 Id 类型不会激增。我将研究自定义 Deserializer 方法,因为它可能是最有效的。
    • 我建议你的反序列化器应该只弄清楚Id 的哪个实现要反序列化,然后委托Jackson 反序列化到那个具体类型。这将使任何关于具体类型的 Jackson 注释仍然受到尊重。 (确保将@JsonDeserialize(using = None.class) 放在具体类型上以避免无限反序列化循环)
    • HiJon 是个好主意,但我这样做似乎遇到了问题;当我调用 mapper.readValue(jsonParser, ConcreteType) 时出现以下错误:“由于输入结束,没有要映射的内容”,其中 jsonParser 是传递给反序列化方法的类型,而 ConcreteType 是我确定的类型是正确的。有任何想法吗?我觉得这与 API 的流式传输特性有关。
    • 是的,JsonParser 正在流式传输,您需要保留对您读取的对象的引用,并在确定后将其转换为具体类型,我为此添加了代码示例。跨度>
    • 知道了!谢谢。我要将此切换为已接受的答案。
    【解决方案2】:

    使用 @JsonIgnore 注释您的方法

    @JsonIgnore
    Thing toThing() {
        new PackageIdentifiedThing(packageId, thingId)
    }  
    

    【讨论】:

      【解决方案3】:

      使用 Jackson2,您可以使用泛型轻松编组到不同的类:

      private <T> T json2Object(String jsonString, String type, Class<T> clazz) {
          JsonNode jsonObjectNode = getChildNode(jsonString, type);       
          T typeObject = null;
          try {
              typeObject = jacksonMapper.treeToValue(jsonObjectNode, clazz);
          } catch (JsonProcessingException jsonProcessingException) {
              LOGGER.severe(jsonProcessingException);
          }
          return typeObject;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多