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

Jackson JSON对嵌套类的集合给出了异常

养俊驰
2023-03-14
问题内容

Jackson JSON序列化/反序列化此类没有问题:

public class MyClass {
   public class Nested {
      public String string;
      public Nested() {}
   }
   public Nested nestedVar;
}

但是在这一点上:

public class MyClass {
   class Nested {
      public String string;
      public Nested() {}
   }
   public Nested nestedVar;
   public List<Nested> nestedList;
}

反序列化时出现此异常:

com.fasterxml.jackson.databind.JsonMappingException:没有为类型[简单类型,类test.MyClass
$
Nested]找到合适的构造函数:无法从JSON对象实例化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?),网址为[Source:java.io.StringReader@26653222;
行:1,列:48](通过参考链:test.MyClass [“ nestedList”]-> java.util.ArrayList [0])

在第一种情况下,Jackson处理嵌套类的实例没有问题,但在第二种情况下没有问题。

我必须编写自定义解串器吗?

测试代码(Jackson 2.6.3):

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class ATest {

   public static void main(String[] args) throws IOException {

      ObjectMapper mapper = new ObjectMapper();

      StringWriter sw = new StringWriter();

      MyClass myClass = new MyClass();

      MyClass.Nested nestedVar = myClass.new Nested();

      List<MyClass.Nested> nestedList = new ArrayList<>();

      nestedList.add(nestedVar);

      myClass.nestedList =nestedList;

      myClass.nestedVar = nestedVar;

      mapper.writeValue(sw, myClass);

      System.out.println(sw.toString());

      StringReader sr = new StringReader(sw.toString());

      MyClass z = mapper.readValue(sr, MyClass.class);
}

}


问题答案:

看起来非静态内部类的识别是在它们直接是其包含bean的属性的情况下完成的(BeanDeserializerBase.java2.6.3中的476行)。因此,中间的Collection反序列化器将超越此范围。自定义解串器可能是这里最简单的选项。

请注意,您仍然可以使用杰克逊阅读的特性Nested,只是实现它自己的结构,在自定义解串器 反序列化的列表时使用Nested的对象。

为此,请像这样注释列表:

    @JsonDeserialize(contentUsing = NestedDeserializer.class)
    public List<Nested> nestedList;

然后使用自定义解串器,它将:

  1. 在调用时查找解析上下文以查找包含的MyClass实例。

  2. 封装默认的/根级别的反序列化器,Nested以委派将内容反序列化的工作。

例如:

public static final class NestedDeserializer extends StdDeserializer<MyClass.Nested>
    implements ResolvableDeserializer {
  private JsonDeserializer<Object> underlyingDeserializer;

  public NestedDeserializer() {
    super(MyClass.Nested.class);
  }

  @Override
  public void resolve(DeserializationContext ctxt) throws JsonMappingException {
    underlyingDeserializer = ctxt
        .findRootValueDeserializer(ctxt.getTypeFactory().constructType(MyClass.Nested.class));
  }

  @Override
  public Nested deserialize(JsonParser p, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    JsonStreamContext ourContext = p.getParsingContext();
    JsonStreamContext listContext = ourContext.getParent();
    JsonStreamContext containerContext = listContext.getParent();
    MyClass container = (MyClass) containerContext.getCurrentValue();
    MyClass.Nested value = container.new Nested();
    // note use of three-argument deserialize method to specify instance to populate
    underlyingDeserializer.deserialize(p, ctxt, value);
    return value;
  }
}


 类似资料:
  • 我有一个实体根 集合项“col”本身具有嵌入对象 EMB“对象非常简单 我希望数据库表是这样的 表:根字段:ID 表:ROOT_COLS字段:ROOT_ID,EMB_FIELD 启动这个spring boot应用程序会给我一个ArrayIndexOutOfBoundsException 如何修复此问题? hibernate版本:5.0.12 null

  • 问题内容: 我在Scala和Java之间遇到编译问题。 我的Java代码需要一个 我的scala代码有一个 我收到编译错误: 似乎scala.collection.JavaConversions不适用于嵌套集合,即使Vector可以隐式转换为Iterable。除了遍历scala集合并手动进行转换之外,我还能做些什么使这些类型起作用? 问题答案: 应该弃用恕我直言。您最好使用来明确说明转换的时间和地

  • 我有三个实体主题、主题和类别。在检索包含主题和主题的所有类别时,如何预取每个实体的id和名称列?我不需要其他字段,因为它会影响性能。

  • 我使用了这个config允许将嵌套对象解析为json: 它似乎确实起到了作用,因为带有嵌套对象的工作正常。然后我尝试从json创建一个类实例https://pub.dev/packages/json_serializable: 我得到一个例外: 抛出的异常:类型'_InternalLinkedHashMap 这是的值: 红色覆盖的值是字符串。当和为时,没有错误。 我认为这是因为是嵌套的JsonSe

  • 是否可以人为地创建一个对象,它将是特定指定类型的集合的定义?如果我有一个命名的集合字段,我可以有正确的定义,即。像这样的类中的字段 我可以通过以下代码提取我需要的所有信息。 这产生: 但是我不知道如何仅通过反射创建这样的<code>ParameterizedType</code>。 换句话说,我需要一个通用的解决方案,以便通过以下测试代码:

  • 本文向大家介绍Python 语言嵌套集合,包括了Python 语言嵌套集合的使用技巧和注意事项,需要的朋友参考一下 示例 导致: 而是使用frozenset: