Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用jackson实现java中的嵌套自定义反序列化_Java_Json_Serialization_Jackson_Deserialization - Fatal编程技术网

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