由于外部原因,我的系统中的所有java Map
只能从客户端以键-值对的 * 列表 * 形式接收,例如,Map<String, Book>
实际上将以JSON序列化的List<MapEntry<String, Book>>
形式接收。这意味着我需要自定义Json反序列化过程,以获得这种Map表示。
问题是JsonDeserializer
让我实现了
deserialize(JsonParser p, DeserializationContext ctxt)
方法,该方法无法访问它应该反序列化的检测到的泛型类型(在上面的示例中为Map<String, Book>
)。如果没有该信息,我就无法在不失去类型安全的情况下反序列化List<MapEntry<String, Book>>
。
我在看Converter,但它给出的上下文更少。
例如:
public Map<K,V> convert(List<MapToListTypeAdapter.MapEntry<K,V>> list) {
Map<K,V> x = new HashMap<>();
list.forEach(entry -> x.put(entry.getKey(), entry.getValue()));
return x;
}
但这可能会创建危险的Map,在检索时会抛出ClassCastException
,因为没有办法检查类型是否实际上是合理的。有办法解决这个问题吗?
作为一个我所期望的例子,Gson的JsonDeserializer
看起来像这样:
T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
也就是说,它以一种正常的方式提供对预期类型的访问。
1条答案
按热度按时间5f0d552i1#
直接从作者那里得到了Jackson谷歌组的答案。
要理解的关键是**
JsonDeserializer
只被初始化/上下文化一次**,它们只在那一刻接收完整的类型和其他信息。为了获得这些信息,反序列化器需要实现ContextualDeserializer
。它的createContextual
方法被调用来初始化一个反序列化器示例,并且可以访问BeanProperty
,它也提供了完整的JavaType
。所以最后看起来可能是这样的:
注册并正常使用: