我正在解析JSON,并且遇到一个可能有三种形式之一的结构有困难。在我的情况下,它可以是零维,一维或二维。有没有什么方法可以动态检查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" ]]
}
我可能正在寻找的是杰克逊将永远匹配的通用课程。
像翻译一样:
{
"SomeField": "SomeValue",
...
"details":{
...
}
}
分为:
class MyClass {
String SomeField;
...
AClass details;
}
是否有一个类AClass
我可以定义它可以是任何JSON结构或数组的通用接收者?
答案 0 :(得分:3)
感谢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<Info> {
public InfoDeserializer() {
super(Info.class);
}
@Override
public Info deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Class<? extends Info> 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);
答案 1 :(得分:2)
这个结构对于AClass来说是你想要的吗?
class Dimension {
String name;
List<String> possibleValues;
}
class Product {
String name;
List<Dimension> dimensions;
}
您需要做的就是更改dimensions
列表的长度以考虑这三种类型。
解析成为检查JSON中是否存在Dimensions
属性的一个微不足道的问题,如果是,则迭代它并附加到dimensions
列表。
另一个想法是重构JSON(如果可以的话),以便所有案例都具有相同的形式:
"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" ]
}
}