任何泛型类型的List属性的Jackson反序列化器

时间:2018-02-28 07:11:43

标签: java jackson

我有像

这样的课程
public class ClassA{
    private String id;
    private List<ClassB> bClass;
}

public class ClassB{
    private int id;
}

public class ClassC{
    private String id;
    private List<ClassD> dClass;
}

public class ClassD{
    private String name;
}

我正在从源代码中读取json,我可以将其反序列化为ClassAClassC对象。我打算为此任务编写一个自定义反序列化器,如下所示:

public class StringToObjectDeserializer extends StdDeserializer<List<B>> {
    public StringToObjectDeserializer() {
        this(null);
    }

    public StringToObjectDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public List<B> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode jsonObject = p.getCodec().readTree(p);
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(jsonObject.textValue(), new TypeReference<List<B>>() {
        });
    }
}

正如您所看到的那样,我正在将反序列化器的返回对象键入为List<B>。我想要的是有一个反序列化器,它将返回List<B>List<D>,具体取决于被反序列化的对象属性。这是因为两个反序列化器具有相同的逻辑,唯一的区别在于键入。我知道类型擦除是在运行时发生的,但有什么方法可以解决这个问题吗?

我已经尝试public class StringToObjectDeserializer extends StdDeserializer<List>作为签名,但它只返回一个无法映射到对象列表的哈希映射。

我想通过注册SimpleModule来使用解串器:

SimpleModule deSerializerModule = new SimpleModule();
        deSerializerModule.addDeserializer(<what to put here?>, new StringToObjectDeserializer());
        ObjectMapper mapper = new ObjectMapper()
                .registerModule(deSerializerModule);
        List<A> listA = mapper.readValue(mapper.writeValueAsString(readJson), new TypeReference<List<A>>() {});

感谢任何帮助!

修改

我需要自定义反序列化器的原因是需要解析2种不同类型的json输入:

类型1:

{
    "id":"abc123",
    "bClass":[{
        "id":123
    },{
        "id":456
    }]
}

类型2:

{
    "id":"abc123",
    "bClass":"[{\"id\":123},{\"id\":456}]"
}

类型1可以由杰克逊本身轻松解析,我确实在一个地方这样做,但处理类型2是挑战,因为它是一个json数组的字符串表示。

目前我有一个hack到位,它将输入从Type 2手动转换为Type 1,然后再通过mapper,但我发现它并不优雅。

0 个答案:

没有答案