前一天在项目里使用了mongo的多态支持,十分好用,但是后台的问题是解决了,伴生的前端多态支持也是个问题。mongo基于morphia的多态支持是在写入mongo的entity时,在entity上补上了相应的className字段,jackson也有类似的处理。本文描述的主题就是基于jackson的反序列化多态问题。
基于jackson 的JsonTypeInfo实现的反序列化多态
jackson本身提供了对多态反序列化的支持JacksonPolymorphicDeserialization,具体实现可以参考上述文档。
这种方式在使用时和morphia的多态实现非常相似。但是不同的是morphia在将数据持久化到db中是就已经附带定义了实体数据的类型,而对于api之类而言是无法知道数据类型的,client端在数据传输时只能指定数据而无法给出具体数据类型。所以这种方式无法适用于依赖客户端创建的数据,纯粹由服务端管理创建的资源更加适用,因为服务端在跟client端交互时jackson会自动附加上类型值(只在序列化和反序列化中存在),这个值并不影响实体的使用。
自定义JsonDeserializer
另外一种稍微傻点的方式就是,自定义json Deserializer方式,好处就是可以随意管理反序列化和序列化方式。可以解决的第一种方法无法支持的创建时多态。恶心的点在于如何界定json属于指定的反序列化方式,第一种方式是在json中制定了类型,但是抱歉的时这里什么都没有。当然最不济的就是根据具体的属性名类反推类型,但是这样强行多态真的好么,直接依赖属性名,依赖一个还是多个,又新加了一个类,特有属性和别的一样怎么办?判断属性全不全来分辨具体类型?
一个讨巧的做法就是在创建资源是给定类型字符,这是没办法避免的一个步骤,不然就真的只能属性值判断了。还可以将deserilizer method使用多态定义到具体类里,这样使用起来也相对方便一点。