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: 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 处理嵌套类的实例没有问题,但在第二种情况下则不然。
我必须编写自定义反序列化器吗?
测试代码(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
2.6.3 中的第 476 行)。因此,一个干预的 Collection 反序列化器将超越它。自定义反序列化器可能是这里最简单的选择。
请注意,您仍然可以使用 Jackson 来读取 Nested
的属性,并自己实现它的构造,在反序列化列表时使用的自定义反序列化器仅 嵌套
对象。
为此,请像这样注释列表:
@JsonDeserialize(contentUsing = NestedDeserializer.class)
public List<Nested> nestedList;
然后使用自定义反序列化器:
调用时查看解析上下文以查找包含的
MyClass
实例。封装
Nested
的默认/根级反序列化器,以将反序列化内容的工作委托(delegate)给。
例如:
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;
}
}
关于java - Jackson JSON 给出了嵌套类集合的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33707023/