杰克逊反序列化嵌套多态类型 [英] Jackson deserializing nested polymorphic type

查看:189
本文介绍了杰克逊反序列化嵌套多态类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Jakson反序列化嵌套的多态类型。这意味着我的顶级类型引用另一个多态类型,最终由不是抽象的类扩展。这不起作用,它会引发异常。

I'm trying to use Jakson to deserialize a nested polymorphic type. Meaning my top level type referes to another polymorphic type that finally is extended by class that's not abstract. This does not work and it throws an exception.

这是我正在尝试做的一个简化示例。

Here is a reduced example of what I'm trying to do.

package com.adfin;

import junit.framework.TestCase;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;

public class JaksonDouble extends TestCase {

  @JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "name"
  )
  @JsonSubTypes({
    @JsonSubTypes.Type(value = SecondLevel.class, name = "SECOND")
  })
  public static abstract class FirstLevel {
    public abstract String getTestValue();
  }

  @JsonTypeInfo(
    use = JsonTypeInfo.Id.CLASS,
    include = JsonTypeInfo.As.PROPERTY,
    property = "@class"
  )
  public static abstract class SecondLevel extends FirstLevel {

  }

  public static class FinalLevel extends SecondLevel {
    String test;
    @Override public String getTestValue() { return test; }
  }

  public void testDoubleAbstract() throws IOException {
    String testStr = "{ \"name\": \"SECOND\", \"@class\": \"com.adfin.JasksonDouble.FinalLevel\", \"test\": \"foo\"}";

    ObjectMapper mapper = new ObjectMapper();
    FirstLevel result = mapper.readValue(testStr, FirstLevel.class);
  }
}

我得到关于抽象类型的标准异常。

I get the standard exception about abstract types.

org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.adfin.JaksonDouble$SecondLevel, problem: abstract types can only be instantiated with additional type information at [Source: java.io.StringReader@f2a55aa; line: 1, column: 19]

让我解释一下我的用例。我有一个描述数据工作流程的Json文档。我在一级有一个抽象类型,描述对单个值的操作。我派生了一堆非抽象的类来实现常见的操作(我用@JsonSubTypes注释所有这些)。

Let me explain my use case. I have a Json document describing a workflow on data. I have an abstract type at "level one" describing an operation on a single value. I derive a bunch of classes that are not abstract that implement common operations (I annotate all of them with @JsonSubTypes).

我有一个特殊的@JsonSubTypes被称为 CUSTOM。这是另一个抽象类,表示其他人编写的自定义操作(在普通jar之外),并且可以使用@class属性指定完全限定的类名。看起来Jakson解析器永远不会在第二个lavel类上读取@JsonTypeInfo注释。

I have one special @JsonSubTypes that is called "CUSTOM". This is another abstract class that represents custom operations that someone else wrote (outside of the normal jar) and they can specify a fully qualified class name using the "@class" property. It looks like the Jakson parser never reads the @JsonTypeInfo annotation on the second lavel class.

如何使这个工作。或者至少我怎样才能使这个用例工作。

How can I make this work. Or at least how can I make this use case work.

推荐答案

你的定义搞砸了 - 你试图使用两个类型标识符,类型名称和类。这没有任何意义。您应该选择一种方法,而不是两种方法。

Your definitions are messed up -- you are trying to use two type identifiers, type name AND class. This does not make any sense. You should choose one method or the other, not both.

如果选择Java类名作为类型信息,则只需省略名称。此外,您只需要为 FirstLevel 包含 @JsonTypeInfo ;子类继承此定义。

If you choose Java class name as type information, just leave out the name. Also, you only need to include @JsonTypeInfo for FirstLevel; sub-classes inherit this definition.

如果您更喜欢使用逻辑类型名称,请删除class属性。您还需要使用注释指定子类型列表,或者通过 ObjectMapper 注册它们。

If you prefer use of logical type name, drop the class property. You will also need to specify sub-type list, either with annotation, or by registering them via ObjectMapper.

这篇关于杰克逊反序列化嵌套多态类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆