多态对象的JSON使用者

我正在解析JSON,并且对于一个可以具有三种forms之一的结构有困难。 在我的情况下,它可以是零维,一维或二维。 有什么方法可以动态检查JSON以确定它是哪一个? 或者也许消费它然后计算出它后来的东西。

结构看起来像这样,可以嵌入其他结构中。

"details":{ "Product":"A zero-dimensional Product" }, "details":{ "Product":"A one-dimensional Product", "Dimensions": [ "Size" ], "Labels": [ "XS", "S", "M", "L" ] }, "details":{ "Product":"A two-dimensional Product", "Dimensions": [ "Size", "Fit" ], "Labels": [[ "XS", "S", "M", "L" ],[ "26", "28", "30", "32" ]] } 

我可能正在寻找的是jackson将永远匹配的通用课程。

翻译的东西:

 { "SomeField": "SomeValue", ... "details":{ ... } } 

成:

 class MyClass { String SomeField; ... AClass details; } 

是否有一个我可以定义的类,它可以是任何JSON结构或数组的通用接收者?

感谢Eric的评论指向programmerbruce我设法破解了它。 这是我使用的代码(简化为简化)。

 public static class Info { @JsonProperty("Product") public String product; // Empty in the 0d version, One entry in the 1d version, two entries in the 2d version. @JsonProperty("Dimensions") public String[] dimensions; } public static class Info0d extends Info { } public static class Info1d extends Info { @JsonProperty("Labels") public String[] labels; } public static class Info2d extends Info { @JsonProperty("Labels") public String[][] labels; } public static class InfoDeserializer extends StdDeserializer { public InfoDeserializer() { super(Info.class); } @Override public Info deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { Class variantInfoClass = null; ObjectMapper mapper = (ObjectMapper) jp.getCodec(); ObjectNode root = (ObjectNode) mapper.readTree(jp); // Inspect the `diemnsions` field to decide what to expect. JsonNode dimensions = root.get("Dimensions"); if ( dimensions == null ) { variantInfoClass = Info0d.class; } else { switch ( dimensions.size() ) { case 1: variantInfoClass = Info1d.class; break; case 2: variantInfoClass = Info2d.class; break; } } if (variantInfoClass == null) { return null; } return mapper.readValue(root, variantInfoClass); } } 

并在ObjectMapper安装它:

 // Register the special deserializer. InfoDeserializer deserializer = new InfoDeserializer(); SimpleModule module = new SimpleModule("PolymorphicInfoDeserializerModule", new Version(1, 0, 0, null)); module.addDeserializer(Info.class, deserializer); mapper.registerModule(module); factory = new JsonFactory(mapper); 

这个结构是你想要的AClass吗?

 class Dimension { String name; List possibleValues; } class Product { String name; List dimensions; } 

您需要做的就是更改dimensions列表的长度以考虑这三种类型。

解析成为检查JSON中是否存在Dimensions属性的一个微不足道的问题,如果是,则迭代它并附加到dimensions列表。


另一个想法是重构JSON(如果可以的话),以便所有情况都是相同的forms:

 "d0":{ "Product":"A zero-dimensional Product", "Dimensions": {} }, "d1":{ "Product":"A one-dimensional Product", "Dimensions": { "Size": [ "XS", "S", "M", "L" ] } }, "d2":{ "Product":"A two-dimensional Product", "Dimensions": { "Size": [ "XS", "S", "M", "L" ], "Fit": [ "26", "28", "30", "32" ] } }