当前位置: 首页 > 面试题库 >

无法在杰克逊中对包含多态项的列表进行反序列化

管炳
2023-03-14
问题内容

我有一个我未定义的(反)序列化JSON问题。

以下是解释此问题的一些代码和JSON:

码:

public static class Base {
    public String klass = "base";
}

public static class SubBase extends Base {
}

public static class Sub1 extends SubBase {
    public Sub1() {
        klass = "Sub1";
    }
}

public static class Sub2 extends SubBase {
    public Sub2() {
        klass = "Sub2";
    }
}

public static class Holder {
    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_ARRAY, property="type")
    @JsonSubTypes({@JsonSubTypes.Type (name = "sub1", value = Sub1.class),@JsonSubTypes.Type(name = "sub2", value = Sub2.class)})
    public List<Base> items = new ArrayList<Base>();
}


Holder holder = new Holder();
holder.items.add(new Sub1());
holder.items.add(new Sub1());

mapper.writeValueAsString(holder);

产生

{"items":[["sub1",{"klass":"Sub1"}],["sub1",{"klass":"Sub1"}]]}

如果我将JsonTypeInfo批注更改为

    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT, property="type")

产生

{"items":[{"sub1":{"klass":"Sub1"}},{"sub1":{"klass":"Sub1"}}]}

到目前为止,一切都很好:)

但是,我从服务器获取的JSON具有稍微不同的结构:

{"type":"sub1", "items":[{"klass":"Sub1"},{"klass":"Sub1"}]}

在“类型”属性中定义了项数组的类型的地方(请注意,“项”数组中的所有项都属于同一类)。
我只是不知道要使用哪种JsonTypeInfo组合来实现此目的。我尝试将“包含”设置为“ .EXTERNAL_PROPERTY”,但这不起作用。
使用此包含项进行反序列化会给我“ 线程“主 ”中的 异常”
org.codehaus.jackson.JsonGenerationException:无法编写字段名称,期望值
”错误消息。

我的问题是:我需要使用哪种注释,以便’ {“ type”:“ sub1”,“ items”:[{“ klass”:“ Sub1”},{“ klass”:“
Sub1”}]}}
‘将基于Holder 的“ type ”属性,用所有Sub1实例填充“ items”数组?
如果这是不可能的话,还有另一种方法可以做到这一点(不需要Holder的自定义序列化程序;仅用于’items’数组的自定义序列化程序就可以了)?

谢谢!


问题答案:

无法映射自动显示的JSON。它不是Jackson支持的4种类型之一。

如果不能使服务器产生更多标准结构(存在自动支持),则需要编写一个自定义解串器;或分两步进行数据绑定,首先进入易于绘制的中间结构(如JsonNodeMap),然后使用该方法将其从所需的结构手动提取类型(例如,使用ObjectMapper.convertValue(object, resultType)。)。



 类似资料:
  • 我在一个文件中有以下 JSON 当我使用Jackson将其反序列化为Java对象时,我得到以下错误 我正在使用以下代码 object mapper mapper = new object mapper(); 我已经为初始数组使用了类型引用,但如何将类型引用用于对象EnrolledEnrolment内的hashmap。 当它尝试解析第二个数组时抛出错误?有什么想法吗? 谢谢

  • 问题内容: 我有一个JSON字符串,将标记为而不是。因此,例如,如果我有一个没有子对象的对象,我将收到类似以下的字符串: 我想将其反序列化为Parent类,并将子级正确设置为一个空的子级列表。 对于上述JSON字符串,我想要一个对象,其设置为,而设置为。 我会知道如何在整个课堂上使用注释 然后 但是,我想解决一个从字符串正确实例化List的一般问题: 我能得到类似的东西吗? 问题答案: 几个选择;

  • 我在spring-boot项目中使用Jackson和hibernate: 并将其添加到转换器中: 我使用facebook网络钩子在Messenger中重新获取关于新消息的信息: 有效负载参数是一个字符串,但jackson转换器无法对其进行反序列化: W.S.M.S.DefaultHandlerExceptionResolver:未能读取HTTP消息:org.springframework.HTTP

  • 问题内容: 我正在创建具有嵌套列表的API。杰克逊似乎是创建对象的好工具,但我还不太清楚如何嵌套列表,我想知道它是否可能。 我的对象看起来像这样。 我希望有一种将其映射到看起来像这样的json的方法: 我们希望能够做到这一点,因此我们可以将属性添加到列表中。 问题答案: 您可以为编写自定义解串器。请参见以下示例: 现在,您必须通知Jackson将其用于您的财产。您可以通过以下方式执行此操作:

  • 问题内容: 我有一个叫做抽象类,然后两个是实现,和。我遇到的问题是,当我将a的其余端点调用到数据库中时,理想情况下,我希望它像将实例传递给REST端点的位置一样。如果不是用一个以上的实现来抽象,那就没问题了,但是由于我有2个,所以我得到了一个错误。 “问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么被其他类型信息实例化” 在找到解决方案之后,我找到了一个SO答案,说我可以使用类

  • 问题内容: 我有以下JSON: 当日期每次更改时,我该如何解析呢?我必须使用Jackson进行解析。 问题答案: 当您具有 动态键时 ,可以使用。键的类型和值取决于您的需要。 最简单的方法是。您需要为此: 假设您的密钥是 有效日期 ,则可以使用。 需要以下依赖项: 然后您可以拥有: 最后,您可以将动态键的值映射到Java类。让我们称之为: 然后您可以拥有: