我有像
这样的课程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,我可以将其反序列化为ClassA
或ClassC
对象。我打算为此任务编写一个自定义反序列化器,如下所示:
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,但我发现它并不优雅。