Jackson JSON在嵌套类的集合上给出了异常 [英] Jackson JSON gives exception on collection of nested class

查看:1000
本文介绍了Jackson JSON在嵌套类的集合上给出了异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Jackson JSON has no problem serializing/deserializing this class:

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;
}

我在反序列化时遇到此异常:

I get this exception when deserializing:


com.fasterxml.jackson.databind.JsonMappingException:找不到类型[simple type,class test.MyClass $ Nested]的合适构造函数:无法从JSON对象实例化(缺少默认值)构造函数或创建者,或者可能需要添加/启用类型信息?)
at [来源:java.io.StringReader@26653222; line:1,column:48](通过引用链:test.MyClass [nestedList] - > java.util.ArrayList [0])

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class test.MyClass$Nested]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: java.io.StringReader@26653222; line: 1, column: 48] (through reference chain: test.MyClass["nestedList"]->java.util.ArrayList[0])

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

In the first case, Jackson has no problem dealing with an instance of a nested class, but not in the second case.

我必须写一个自定义解串器?

Must I write a custom deserializer?

测试代码(Jackson 2.6.3):

Test code (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.java 第476行在2.6.3)。因此,干预的集合解串器将超越它。自定义反序列化器可能是最简单的选项。

Looks like the recognition of non-static inner classes is done where they are properties directly on their containing bean (BeanDeserializerBase.java line 476 in 2.6.3). So an intervening Collection deserializer would go past that. A custom deserializer is likely the simplest option here.

请注意,您仍然可以使用Jackson来读取 Nested ,并且只需在反序列化嵌套对象列表时使用的自定义反序列化器 中自行构建它。

Note that you can still use Jackson to read the properties of Nested, and just implement the construction of it yourself, in a custom deserializer only used when deserializing a list of Nested objects.

要执行此操作,请按以下方式注释列表:

To do this, annotate the list like so:

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

然后使用自定义反序列化器:

and then use a custom deserializer that will:


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

封装嵌套的默认/根级反序列化程序,以将反序列化内容的工作委托给。

Encapsulate a default/root-level deserializer of Nested to delegate the work of deserializing the content to.

例如:

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;
  }
}

这篇关于Jackson JSON在嵌套类的集合上给出了异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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