当前位置: 首页 > 知识库问答 >
问题:

使用Jackson反序列化时缺少字段(多态)

纪佐
2023-03-14

我正在尝试为接受JSON输入的前端库创建一个java SDK。本质上,此SDK将特定类型的对象转换为JSON,然后由前端库使用。

我正在使用杰克逊的多态序列化/反序列化使用它的注释系统。

我有一个基类a和扩展a的两个子类B和C。类a有一个类型字段,我用它来决定要使用哪个类(B或C)。语法如下所示:

@JsonTypeInfo({
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.EXISTING_PROPERTY,
  property= "type"
})
@JsonSubTypes({
  @JsonSubTypes.Type(value = B.class, name = "b"),
  @JsonSubTypes.Type(value = C.class, name = "c")
})
public class A {
  private String type;

  public void setType(String type){
    this.type = type;
  }

  public String getType(){
    return this.type;
  }
}

public class B extends A {

}

public class C extends A {

}

现在,当我使用Jackson的ObjectMapper函数读取字符串化的JSON并转换为类A时,我根据类型变量的值得到了类A或类B的正确实例。然而,这是实际的问题,当我尝试使用函数getType时,我总是在这些对象中得到null。我不知道为什么jackson没有在对象上设置这些值。

String json = "{ type: 'b' }"; // example input json

ObjectMapper om = new ObjectMapper();
A a = om.readValue(json, A.class);
// a is actually an instance of class B

a.getType()// this is null

共有1个答案

桂志诚
2023-03-14

您需要向JsonTypeInfo添加参数visible=true,以避免在反序列化时删除类型。

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.EXISTING_PROPERTY,
  property= "type",
  visible = true
)

public abstract boolean visible()默认值为false

定义类型标识符值是作为JSON流的一部分传递给反序列化器(true),还是由TypeDeserializer处理和删除(false)的属性。属性对序列化没有影响。默认值为false,这意味着Jackson从传递给JsonDeserializer的JSON内容中处理和删除类型标识符。

 类似资料:
  • 我的JSON字符串是: 我想要实现的是,当JSON中没有提供schemaVersion时,能够在默认情况下反序列化到SubClassV1,但即使在Superclass中将schemaVersion初始化为“1.0”时,我仍然会收到以下错误:

  • Jackson版本:2.10.1 谢谢你的回答!

  • 我有这样一门课: 我知道基于typeToClassId的对象obj是什么类型,不幸的是只有在运行时才知道。 我想基于typeToClassId解析出obj——这里最好的方法是什么?注释似乎已经过时了,基于ObjectMapper的东西似乎是对的,但我很难弄清楚最好的方法可能是什么。 类似于类clazz=lookUpClassBasedOnId(typeToClassId)objectMapper的

  • 我对Jackson和类型层次结构有以下问题。我正在序列化一个类SubA,该类将扩展为一个字符串,然后尝试将其反序列化回来。当然,在编译时,系统不知道它是基还是SubA,因此我希望它是基,如果它是SubA,则会在编译后执行一些其他操作。 我的基本类看起来像: ...和一个派生自的类: ... 我试图执行以下代码: String是: 但我一次又一次地犯同样的错误。映射器现在知道如何处理另一个类参数-它

  • 我有以下xml 我需要将其反序列化为以下POJO: 这里的问题是被包装在元素中

  • 如果我给它一些JSON,比如: 并使用读取 我得到一个类似。