用jackson实现java中的嵌套自定义反序列化
我一直在想如何正确地解决这个问题 我有这样一个数据模型:用jackson实现java中的嵌套自定义反序列化,java,json,serialization,jackson,deserialization,Java,Json,Serialization,Jackson,Deserialization,我一直在想如何正确地解决这个问题 我有这样一个数据模型: Class B String fieldB1; String fieldB2; Class A String fieldA1; String fieldA2; List<B> fieldA3; B类 字符串字段B1; 字符串字段B2; 甲级 字符串字段1; 字符串字段A2; 列表字段A3; (然后是另一个第三个类,它与另一个类具有相同的层次结构,具有字段和对象列表,但为了简单起见,让我们继续使用a和B) 现在,
Class B
String fieldB1;
String fieldB2;
Class A
String fieldA1;
String fieldA2;
List<B> fieldA3;
B类
字符串字段B1;
字符串字段B2;
甲级
字符串字段1;
字符串字段A2;
列表字段A3;
(然后是另一个第三个类,它与另一个类具有相同的层次结构,具有字段和对象列表,但为了简单起见,让我们继续使用a和B)
现在,在另一方面,我必须用相同名称的类和不同数据类型的参数反序列化这些类
因此^必须改为:
Class B
int fieldB1;
double fieldB2;
Class A
float fieldA1;
float fieldA2;
List<B> fieldA3;
B类
int fieldB1;
双字段B2;
甲级
浮子场A1;
浮子场A2;
列表字段A3;
由于我没有经验,我的第一个猜测是在jackson中为A和B编写自定义反序列化程序,当我反序列化像B这样的类时,它没有使用自定义反序列化方法引用其他类,转换很容易
但是为类a创建自定义反序列化程序怎么样?当我必须反序列化字段A3(也称为B对象列表)时,我应该如何操作?是否应尝试以某种方式在ClassACustomDeserializer中调用ClassBCustomDeserializer?怎么做?
或者有没有另一个更简单的解决方案,让jackson根据我的个人映射转换其他类型的字符串字段
这就是我反序列化B的方式
public class BDeserializer extends StdDeserializer<B> {
public BDeserializer() {
this(null);
}
public BDeserializer(Class<?> vc) {
super(vc);
}
@Override
public B deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
int fieldB1= node.findValue("fieldB1").asInt();
double fieldB2= node.findValue("fieldB2").asDouble();
return new B(fieldB1,fieldB2);
}
}
public类序列化程序扩展StdDeserializer{
公共序列化程序(){
这个(空);
}
公共序列化程序(类vc){
超级(vc);
}
@凌驾
公共B反序列化(JsonParser jp,反序列化上下文ctxt)
抛出IOException、JsonProcessingException{
JsonNode节点=jp.getCodec().readTree(jp);
int fieldB1=node.findValue(“fieldB1”).asInt();
double fieldB2=node.findValue(“fieldB2”).asDouble();
返回新的B(字段B1、字段B2);
}
}
Jackson足够聪明,可以将文本值转换为适当的数字类型,因此它应该能够反序列化JSON,如:
{ "fieldB1": 10, "fieldB2" : "0.333" }
给你
Class B
int fieldB1;
double fieldB2;
很好,甚至没有使用自定义反序列化器
如果您想坚持使用自定义反序列化程序,无论出于何种原因,
您可以使用JsonNode.traverse()创建子解析器:
JsonParser parser = node.findValue("fieldA3").traverse();
parser.setCodec(jp.getCodec());
List<B> list = parser.readValueAs(new TypeReference<List<B>>() {});
如果性能值得关注,后者应该更高效。非常感谢。因为我需要“转换”的一些东西有时是类,我需要一个简单的字段,所以我想我会采用反序列化的方式,尽管我可以使第一个也能工作。
while(jp.nextToken() != JsonToken.END_OBJECT) {
if(jp.currentToken() == JsonToken.FIELD_NAME) {
switch (jp.getCurrentName()) {
//...
case "fieldA3":
jp.nextToken();
list=jp.readValueAs(new TypeReference<List<ClassB>>() {}));
break;
}
}
}