Pie*_* dS 9 java serialization json jackson
Jackson JSON序列化/反序列化这个类没有问题:
public class MyClass {
public class Nested {
public String string;
public Nested() {}
}
public Nested nestedVar;
}
Run Code Online (Sandbox Code Playgroud)
但在这一个:
public class MyClass {
class Nested {
public String string;
public Nested() {}
}
public Nested nestedVar;
public List<Nested> nestedList;
}
Run Code Online (Sandbox Code Playgroud)
反序列化时遇到此异常:
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])
在第一种情况下,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);
}
Run Code Online (Sandbox Code Playgroud)
}
看起来非静态内部类的识别是在它们是包含bean的直接属性的情况下完成的(BeanDeserializerBase.java2.6.3中的第476行).因此,干预的集合解串器将超越它.自定义反序列化器可能是最简单的选择.
请注意,您仍然可以使用杰克逊阅读的特性Nested,只是实现它的建设自己,在自定义解串器只反序列化的列表时使用Nested的对象.
为此,请像这样注释列表:
@JsonDeserialize(contentUsing = NestedDeserializer.class)
public List<Nested> nestedList;
Run Code Online (Sandbox Code Playgroud)
然后使用自定义反序列化器:
在调用查找包含MyClass实例时查看解析上下文.
封装默认/根级反序列化器,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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8230 次 |
| 最近记录: |