使用父 属性 值对 jackson 进行多态反序列化
Polymorphic deserialization of jackson using parent property value
我有一个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 转换为它们的 pojos,即正则表达式、转换。我试过下面的代码。
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;
}
}
正则表达式Rule.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 反序列化为 pojo 时,我得到的名称为 null。相反,我应该得到 regex
和 transform
作为输出
我在这里犯了什么错误?我需要工厂方法的名称
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
我有一个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 转换为它们的 pojos,即正则表达式、转换。我试过下面的代码。
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;
}
}
正则表达式Rule.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 反序列化为 pojo 时,我得到的名称为 null。相反,我应该得到 regex
和 transform
作为输出
我在这里犯了什么错误?我需要工厂方法的名称
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
相同
- 您可以从 POJO 中删除
As.EXISTING_PROPERTY
- 将按您的预期填充该字段,但在规模上性能可能略差(仅当应用程序持续执行此操作时才重要)
- 另一个例子见original feature request