我目前正在努力解决 JSON 数据结构的反序列化问题,如下所示:
示例 1:
{
"condition": "AND",
"rules": [
{
"id": "FIELD1",
"field": "FIELD1",
"type": "string",
"input": "select",
"operator": "equal",
"value": [
"a1"
]
},
{
"id": "FIELD2",
"field": "FIELD2",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"b1"
]
}
]
}
示例 2:
{
"condition": "AND",
"rules": [
{
"id": "FIELD1",
"field": "FIELD1",
"type": "string",
"input": "select",
"operator": "equal",
"value": [
"a1"
]
},
{
"id": "FIELD2",
"field": "FIELD2",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"b1",
"b2",
"b3"
]
},
{
"id": "FIELD3",
"field": "FIELD3",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"c1",
"c2",
"c3"
]
},
{
"id": "FIELD4",
"field": "FIELD4",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"d1",
"d2",
"d3"
]
},
{
"condition": "AND",
"rules": [
{
"id": "FIELD5",
"field": "FIELD5",
"type": "string",
"input": "select",
"operator": "equal",
"value": [
"e1"
]
},
{
"id": "FIELD6",
"field": "FIELD6",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"f1",
"f1",
"f3",
"f4",
"f5",
"f6"
]
},
{
"condition": "AND",
"rules": [
{
"id": "FIELD7",
"field": "FIELD7",
"type": "string",
"input": "select",
"operator": "in",
"value": [
"g1",
"g2",
"g3"
]
}
]
}
]
}
]
}
我必须处理很多这种结构的实例。它是规则构建器的输出。我无法更改 JSON 的格式,我必须使用我得到的内容。结构是递归的,可以有多个层次。
我正在使用 Jackson 的 ObjectMapper 并构建一些内部类来映射数据。
static class Wrapper {
public Condition condition;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(RuleGroup.class),
@JsonSubTypes.Type(Rule.class) })
public List<AbstractRuleObject> rules;
}
static abstract class AbstractRuleObject {
public Condition condition;
public List<Rule> rules;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(RuleGroup.class),
@JsonSubTypes.Type(Rule.class) })
public List<AbstractRuleObject> ruleGroups;
}
static class RuleGroup extends AbstractRuleObject {
public Condition condition;
public List<Rule> rules;
}
static class Rule extends AbstractRuleObject {
public String id;
public String field;
public String type;
public String input;
public Operator operator;
public List<String> value;
}
大多数实例看起来像示例 1,对于那些它已经可以正常工作的实例,但还有更复杂的实例,例如示例 2,实际上比示例 2 更复杂、更深入,但结构始终相同:
总是有一个“规则组”,其中包含一个“条件”和一个“规则”列表,规则可以是一个“规则”,也可以是一个“规则组”,深度没有限制,但是我相信它不会比4或5层深。每个级别可以有多个“规则组”
我无法解析这些更深入的示例,使用当前代码和示例 2,我收到以下错误:
Could not resolve subtype of [simple type, class MyClass$AbstractRuleObject]: Cannot deduce unique subtype of
MyClass$AbstractRuleObject
(2 candidates match)
最佳答案
Rule 和 RuleGroup 没有任何共同点,只是它们都可以出现在列表中,因此 AbstractRuleObject
不应具有 condition
和 rules
其上 - 规则
没有这些属性。
我们也可以摆脱 Wrapper
,因为它与 RuleGroup
相同。
这对我有用:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
public class ParseExample {
static class RuleObject {
}
static class RuleGroup extends RuleObject {
public String condition;
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(RuleGroup.class),
@JsonSubTypes.Type(Rule.class)})
public List<RuleObject> rules;
}
static class Rule extends RuleObject{
public String id;
public String field;
public String type;
public String input;
public String operator;
public List<String> value;
}
public static void main(String... args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonParser parser = mapper.createParser(ParseExample.class.getClassLoader().getResourceAsStream("test2.json"));
RuleGroup w = parser.readValueAs(new TypeReference<RuleGroup>() {});
}
}
jackson 版本:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
结果:
args = {String[0]@1361} []
mapper = {ObjectMapper@1362}
parser = {UTF8StreamJsonParser@1363}
w = {ParseExample$RuleGroup@1364}
condition = "AND"
rules = {ArrayList@1366} size = 5
0 = {ParseExample$Rule@1368}
1 = {ParseExample$Rule@1369}
2 = {ParseExample$Rule@1370}
3 = {ParseExample$Rule@1371}
4 = {ParseExample$RuleGroup@1372}
condition = "AND"
rules = {ArrayList@1380} size = 3
0 = {ParseExample$Rule@1382}
1 = {ParseExample$Rule@1383}
2 = {ParseExample$RuleGroup@1384}
condition = "AND"
rules = {ArrayList@1386} size = 1
0 = {ParseExample$Rule@1388}
关于java - JSON/ jackson : Recursive polymorphic deserialization without type field,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68855545/