首页 \ 问答 \ 使用Jackson(Polymorphic)进行反序列化时缺少字段(Missing field when deserializing using Jackson (Polymorphic))

使用Jackson(Polymorphic)进行反序列化时缺少字段(Missing field when deserializing using Jackson (Polymorphic))

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

我使用其注释系统使用jackson的多态序列化/反序列化。

我有一个基类A和2个子类B和C扩展A.类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的ObjectMapperreadValue函数并读取字符串化的JSON并转换为A类时,我会根据类型变量的值获得A类或B类的正确实例。 但是 ,这是实际问题,当我尝试使用函数getType我总是在这些对象中得到null 。 我不确定为什么杰克逊没有在对象上设置这些值。

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

I am trying to create an java SDK for a front-end library that takes JSON input. Essentially, this SDK converts objects of certain type into JSON which is then consumed by that front-end library.

I am using jackson's polymorphic serialization/deserialization using its annotation system.

I have a base class A and 2 child classes B and C extending A. Class A has a type field, using which I decide what class (B or C) is to be used. The syntax looks something like this:

@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 {

}

So now, when I use Jackson's ObjectMapper's readValue function and read the stringified JSON and convert to class A, I get the correct instance of either class A or class B based on the value of the type variable. However, and here is the actual problem, when I try to use the function getType I always get null in those objects. I am not sure why jackson is not setting those values on the object.

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

原文:https://stackoverflow.com/questions/40079632
更新时间:2020-10-25 18:40

最满意答案

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

@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内容中删除类型标识符。


You need to add to @JsonTypeInfo the parameter visible = true to avoid to remove the type when deserializing.

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

public abstract boolean visible() default false

Property that defines whether type identifier value will be passed as part of JSON stream to deserializer (true), or handled and removed by TypeDeserializer (false). Property has no effect on serialization. Default value is false, meaning that Jackson handles and removes the type identifier from JSON content that is passed to JsonDeserializer.

2016-10-17

相关问答

更多

Jackson的多态序列化/反序列化和自定义序列化/解串器(Jackson's polymorphic serialization / deserialization AND custom serializer / deserializer)

你可以试试这个: AnnotationIntrospector annotationInspector = new JacksonAnnotationIntrospector(); AnnotatedClass annotatedClass = AnnotatedClass.constructWithoutSuperTypes(OID.class, new ObjectMapper().getSerializationConfig()); List<NamedTyp ...

杰克逊反序列化嵌套多态类型(Jackson deserializing nested polymorphic type)

您的定义搞砸了 - 您正在尝试使用两个类型标识符,类型名称和类。 这没有任何意义。 您应该选择一种方法或另一种方法,而不是两种方法。 如果选择Java类名作为类型信息,则只需省略名称。 此外,您只需要为FirstLevel包含@JsonTypeInfo ; 子类继承了这个定义。 如果您更喜欢使用逻辑类型名称,请删除class属性。 您还需要使用注释指定子类型列表,或者通过ObjectMapper注册它们。 Your definitions are messed up -- you are tryi ...

使用jackson注释反序列化多级别多态性子类型(Deserialize multi level polymorphic subtypes using jackson annotations)

Jackson api不支持多层次的多态类型层次结构。 你可以看看: https : //github.com/FasterXML/jackson-databind/issues/374 所以你需要做的是: 请创建一个反序列化器(对于MySubItem.class,比如MySubItemDeserializerMixin.class),并将其配置为jsonMapper,就像我们为其他Mixin类所做的那样。 mapper.addMixInAnnotations(MySubItem.class, M ...

如何用Jackson JSON和JAVA反序列化多态LinkedList?(How to deserialize polymorphic LinkedList with Jackson JSON and JAVA?)

如果你期望得到一个List,你必须通过一个List类型:在这里你给定了类型的clazz但期望类型的List<T> 。 即使clazz是List类型,这也不起作用。 所以你需要通过适当的类型。 但是对于List(和Map)类型,您还需要指定内容类型:而类型变量不会。 什么起作用就像这样: List<MyType> list = mapper.readValue(jsonSource, new TypeReference<List<MyType>>() { }); 由于Java类型擦除,必须使用Ty ...

使用Jackson使用多态setter方法将JSON反序列化为对象(Deserializing JSON into object with polymorphic setter methods using Jackson)

我已经使用了Jackson的PropertyNamingStrategy,如http://www.javaroots.com/2013/03/how-to-use-naming-in-jackson.html中所述 。 感谢@bhdrkn 我还必须使用以下代码来忽略我的代码工作的未知属性。 ObjectMapper objectMapper = getObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKN ...

如果不存在字段,则杰克逊无法反序列化(Jackson fail deserialization if field is not present)

@JsonProperty具有可以使用的required元素 确保JSON中存在属性值 不幸的是,Jackson目前(2.9)仅支持它与@JsonCreator注释构造函数或工厂方法一起使用。 由于@JsonSetter仅适用于setter,因此您必须自己进行null验证。 例如,您可以定义一个类似的构造函数 @JsonCreator public Pojo(@JsonProperty(value = "string", required = true) String string) { ...

杰克逊多态反序列化(Jackson polymorphic deserialization)

您的代码看起来正确用例。 一个可能的问题是你可能会意外地使用杰克逊2注释与杰克逊1 ObjectMapper (我可以看到后者是杰克逊从包名称例外)。 注释和映射器的版本必须匹配; 否则注释将被忽略,这将解释您所看到的问题。 Your code looks correct for the use case. One possible problem is that you could be accidentally using Jackson 2 annotations with Jackson ...

使用Jackson对具有泛型类型的对象进行反序列化(Deserializing an object with a generic type with Jackson)

我无法解释你的Gson错误。 您遇到的问题在您发布的代码中并不明显。 至于如何使用Jackson工作,使用评论中提到的TypeReference是正确的答案。 但是,这不会一直修复它。 你有很多选择,包括杰克逊注释和/或杰克逊“mixins”。 但是,最容易解决这个问题的方法可能是在你的类中添加getter和setter。 Jackson会检测你的getter和setter,并适当地序列化和反序列化你的对象。 以下代码在很多方面都很简陋,但确实有效。 import com.fasterxml.ja ...

使用Jackson java反序列化派生类(Deserializing a derived class using Jackson java)

您需要在Criteria添加@JsonTypeInfo以启用其他类型信息,以支持多态类型。 你应该能够找到它的例子(只是谷歌的“杰克逊JsonTypeInfo”)。 You will need to add @JsonTypeInfo in Criteria to enable use of additional type information, to support polymorphic types. You should be able to find example of that (j ...

使用Jackson(Polymorphic)进行反序列化时缺少字段(Missing field when deserializing using Jackson (Polymorphic))

您需要将参数visible = true添加到@JsonTypeInfo ,以避免在反序列化时删除该类型。 @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property= "type", visible = true ) public abstract boolean visible()默认为false 定义类型标识符值是作为JSON流的一部分传递 ...

相关文章

更多

最新问答

更多
  • 如何保护Solr只允许SELECT请求给用户并禁止其他任何东西?(How to secure Solr to allow SELECT request to only users and disallow anything else?)
  • XPath表达式无效/错误TFHpple SWIFT 1.2(XPath Expression not working/incorrect TFHpple SWIFT 1.2)
  • css3 3D变换不能平滑地制作动画(css3 3D transform doesn't animate smoothly)
  • 运行时错误'91'和Outlook.Application = <对象变量或没有设置块变量>?(Run-time error '91' & Outlook.Application = Object variable or With block variable not set?)
  • 慢的webservice问题(Slow webservice problem)
  • textview的不正确对齐方式(Improper alignment of a textview)
  • 在第一步“Hello World”中出现Java错误(Cannot run “Hello World” program in Eclipse)
  • 为什么十六进制地址是14个字符?(why the hex address is 14 character?)
  • 如何在Python中的不同类中使用变量?(How to use variable in different classes in Python?)
  • asp:GridView HYPERLINKFIELD - datanavigateurlformatstring中的asp代码(asp:GridView HYPERLINKFIELD - asp code inside datanavigateurlformatstring)
  • 关于adaboost算法(About adaboost algorithm)
  • 在Matlab上内置图像(Built in Images on Matlab)
  • java swing:输入键事件时焦点丢失(java swing: Focus lost on enter key event)
  • C#中的通用约束,T是相同的TSomethingElse,对吧?(Generic constraints in C#, T is the same TSomethingElse, right?)
  • 从mybatis中的光标获取数据(Fetching data from cursor in mybatis)
  • 在运行时从XML构建对象的最佳方法(Best way for building objects out of XMLs at runtime)
  • 在整个窗口中拉伸sf :: Sprite(Stretch sf::Sprite across entire window)
  • Selenium Node API Web驱动程序等待超时处理程序(Selenium Node API web driver wait timeout handler)
  • 函数使用并且是map的一部分(循环依赖?)(Function uses and is part of map (circular dependency?))
  • 是否可以在C ++ 14中使用可选模板参数创建类型元组?(Is possible to make a tuple of types with optional template parameters in C++14?)
  • PHP从窗帘后面打印/ f(PHP prints /f from behind the curtains)
  • JFrame的contentPane的LayoutManager(LayoutManager of JFrame's contentPane)
  • 用于Instagram Feed的图像滚动(Image Roll Overs for Instagram Feed)
  • 如何显示拉伸字体(双倍宽度/高度)?(How to display stretched font (double width/height)?)
  • 文件操作API在fileapi.h和stdio.h中的WP8差异?(WP8 differences between file manipulation APIs in fileapi.h and stdio.h?)
  • 保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())
  • jqgrid中的分页问题与数组数据(Pagination problem in jqgrid with array data)
  • 重定向时,通过其他页面上的URL调用javascript函数(Call javascript function through url on otherpage while Redirecting)
  • 如何使用InvokeCommandAction调用我的方法并传入参数?(How do I go about using InvokeCommandAction to call a method of mine and pass in parameters?)
  • Jquerymobile按钮仅显示页面的第一个外观(Jquerymobile buttons are shown only first apperance of the page)