ContextualDeserializer,用于使用 Jackson 将 JSON 映射到不同类型的映射
此 JSON 片段应映射到一个 Java 对象,其中包含 Map
类型的 cars
字段和 bikes
类型的 bikes
字段输入地图<字符串,自行车>
。因为自行车和汽车在 JSON 文件中可以是空字符串,所以我需要一个自定义反序列化器 (查看这个问题)。
{
"id" : "1234",
"name" : "John Doe",
"cars" : {
"Tesla Model S" : {
"color" : "silver",
"buying_date" : "2012-06-01"
},
"Toyota Yaris" : {
"color" : "blue",
"buying_date" : "2005-01-01"
}
},
"bikes" : {
"Bike 1" : {
"color" : "black"
},
"Bike 2" : {
"color" : "red"
}
}
}
我考虑过拥有一个通用自定义反序列化器的实例,该实例可以由基于 BeanProperty 参数的 ContextualDeserializer
的 createContextual(DeserializationConfig cfg, BeanProperty property)
方法返回。通用自定义反序列化器如下所示:
public class MapsGenericDeserializer<T> extends
JsonDeserializer<Map<String, T>> {
private ObjectMapper mapper; // ObjectMapper without special map deserializer
public MapsGenericDeserializer(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public Map<String, T> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec codec = jp.getCodec();
JsonNode node = codec.readTree(jp);
if (!"".equals(node.getTextValue())) {
return mapper.readValue(node,
new TypeReference<Map<String, T>>() {});
}
return null; // Node was an empty string
}
}
下面的上下文序列化器不起作用,因为从 MapsGenericDeserializer
到 JsonDeserializer
的转换不起作用可能的。也许这在较新版本的 Java 中是可能的,但它不适用于我正在编码的 Android 版本。那么我怎样才能实现所需的行为呢?
public class MapsDeserializer extends JsonDeserializer<Map<String, ?>>
implements ContextualDeserializer<Map<String, ?>> {
private ObjectMapper mapper;
MapsGenericDeserializer<Car> carDeserializer = new MapsGenericDeserializer<Car>(mapper);
MapsGenericDeserializer<Bike> bikeDeserializer = new MapsGenericDeserializer<Bike>(mapper);
public MapsDeserializer(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public JsonDeserializer<Map<String, ?>> createContextual(DeserializationConfig cfg,
BeanProperty property) throws JsonMappingException {
Class<?> targetClass = property.getType().containedType(1).getRawClass();
if(targetClass.equals(Car.class) {
return carDeserializer; // Type mismatch!
} else if (targetClass.equals(Bike.class)) {
return bikeDeserializer; // Type mismatch!
} else {
return this;
}
}
// ...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我可能采取的方法。
泛型类型参数可能有点乱。我做了一些快速复制粘贴。
Here's how I might approach it.
The generic type parameters might be a little out of order. I did a bit of quick copy-pasting.