基于来自 JSON 请求主体的另一个属性,反序列化来自 JSON 请求主体的抽象属性
Posted
技术标签:
【中文标题】基于来自 JSON 请求主体的另一个属性,反序列化来自 JSON 请求主体的抽象属性【英文标题】:Deserializing abstract property from JSON request body, based on another property from that body 【发布时间】:2019-11-07 15:20:20 【问题描述】:当一个对象具有一个抽象属性时,如何从 JSON 中正确反序列化(使用 Jackson)?
这可能最好用一个例子来描述。
我的 REST 端点的请求正文包含一个属性,该属性是具有多个具体实现的抽象类型,应基于 discriminator
属性进行反序列化:
@Getter
@Builder
@AllArgsConstructor
public class SomeRequestBody
@NotNull
@NotBlank
@NumberFormat
private final String discriminator;
@NotNull
private final SomeAbstractClass someAbstractClass;
有问题的抽象类
@Getter
@AllArgsConstructor
public abstract class SomeAbstractClass
@NotNull
@NotBlank
protected final String commonProperty;
抽象类的示例实现
@Getter
public class ConcreteImplementationA extends SomeAbstractClass
@Builder
@JsonCreator
public ConcreteImplementationA(
@NotNull @NotBlank @JsonProperty("commonProperty") String commonProperty,
@NotNull @NotBlank @JsonProperty("specificProperty") Date specificProperty)
super(commonProperty);
this.specificProperty = specificProperty;
@NotNull
@NotBlank
private final String specificProperty;
我尝试了什么...
@Getter
@Builder
@AllArgsConstructor
public class SomeRequestBody
@NotNull
@NotBlank
@NumberFormat
private final String discriminator;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "discriminator")
@JsonSubTypes(
@JsonSubTypes.Type(value = ConcreteImplementationA.class, name = "1"),
Other implementations...)
)
@NotNull
private final SomeAbstractClass someAbstractClass;
但是,我遇到了以下异常:
"Type definition error: [simple type, class abc.SomeRequestBody]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `abc.SomeRequestBody`, problem: Internal error: no creator index for property 'someAbstractClass' (of type com.fasterxml.jackson.databind.deser.impl.FieldProperty)\n at [Source: (PushbackInputStream); line: 8, column: 1]"
实现我需要的正确方法是什么?
【问题讨论】:
【参考方案1】:事实证明,该抽象属性的反序列化不是问题,但不可变属性和 Lombok 的 @AllArgsConstructor
与 Jackson 不兼容。我创建了一个 @JsonCreator 带注释的构造函数,而不是使用注释,现在它可以正常工作了。
【讨论】:
不是构建自己的构造函数,添加它也应该有效@AllArgsConstructor(onConstructor = @__(@JsonCreator))
,至少对我来说它有效。
如果您的大多数对象都是这样不可变的,并且您不想为每个类添加配置详细信息...您可以创建一个 lombik.config
属性为 lombok.anyConstructor.addConstructorProperties=true
的文件它。这将导致 lombok 将 Java 注释添加到构造函数参数,并命名它们,Jackson 可以使用。以上是关于基于来自 JSON 请求主体的另一个属性,反序列化来自 JSON 请求主体的抽象属性的主要内容,如果未能解决你的问题,请参考以下文章
System.Text.Json 反序列化来自 API 调用的嵌套对象 - 数据包装在父 JSON 属性中
使用 JSON-B / Yasson 将 JSON 反序列化为多态 POJO