Jackson JSON在嵌套类的集合上给出了异常 [英] Jackson JSON gives exception on collection of nested class
问题描述
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:
-
在调用时查看解析上下文以查找包含
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屋!