【问题标题】:Polymorphic deserialization of jackson using parent property value使用父属性值对杰克逊进行多态反序列化
【发布时间】:2020-11-21 00:40:35
【问题描述】:

我有一个json如下:

{
    "transformationRules": [
        {
            "targetFieldName": "pageUrlNumber",
            "inputPath": "$.metadata.pageUrl",
            "rules": [
                {
                    "name": "regex",
                    "regexPattern": "\\d+",
                    "regexTransformType": "extract",
                    "order":2
                }
            ]
        },
        {
            "targetFieldName": "categories",
            "inputPath": "$.attributes[0].productInfo.breadCrumbs",
            "rules": [
                {
                    "name": "transform"
                }
            ]
        }
    ]
}

rules数组有不同类的json。

我想根据名称的值(即正则表达式、转换)将上述 json 转换为他们的 pojo。我试过下面的代码。

Rule.java

@NoArgsConstructor
@Data
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
        property = "name")
@JsonSubTypes({
        @JsonSubTypes.Type(value = RegexRule.class, name = "regex"),
        @JsonSubTypes.Type(value = Transform.class, name = "transform"),
})
public abstract class Rule {

    @JsonProperty("name")
    private String name;

    @JsonProperty("order")
    private int order = 1;

    protected Rule(String name, int order) {
        this.name = name;
        this.order = order;
    }

}

RegexRule.java

@NoArgsConstructor
@Data
public class RegexRule extends Rule{

    @JsonProperty("regexPattern")
    private String regexPattern;

    @JsonProperty("regexTransformType")
    private String regexTransformType;

    @JsonProperty("replacementValue")
    private String replacementValue = "";

    @JsonProperty("regexGroupNumber")
    private int regexGroupNumber = 0;

    public RegexRule(String name, int order, String regexPattern, String regexTransformType, String replacementValue, int regexGroupNumber) {
        super(name, order);
        this.regexGroupNumber = regexGroupNumber;
        this.regexPattern = regexPattern;
        this.regexTransformType = regexTransformType;
        this.replacementValue = replacementValue;
    }
}

Transform.java

@NoArgsConstructor
@Data
public class Transform extends Rule{

    public Transform(String name, int order) {
        super(name, order);
    }
}

Main.java

for(TransformationRule transformationRule: getTransformationRules()){
            for(Rule rule:transformationRule.getRules()){
                System.out.println(rule.getName());
            }
        }

输出:

null
null

在我的 Main 函数中,当我将 json 反序列化为 pojos 时,我将 name 设为 null。相反,我应该得到 regextransform 作为输出

我在这里犯了什么错误?我需要工厂方法的名称

【问题讨论】:

    标签: java json jackson jackson-databind jackson2


    【解决方案1】:

    As.EXTERNAL_PROPERTY 在这里听上去是错误的,如果这能奏效我很惊讶,这意味着:

    {
      "name": "regex", // This is the *external* property, one level up
      { // this is the Rule
        "order": 2,
        ...
      }
    }
    

    试试

    • As.PROPERTY
      • 您可以从 POJO 中删除 Rule#name,因为它被视为存在的元数据,以便 Jackson 正确反序列化。请记住 rule.getName()=="regex"rule instanceof RegexRule 相同
    • As.EXISTING_PROPERTY
      • 将按照您的预期填充该字段,但在规模上的性能可能会稍差(仅在应用持续执行此操作时才重要)
      • 另一个例子请参见original feature request

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      相关资源
      最近更新 更多