首先要说的是FastJson提供了一个用于处理泛型反序列化的类TypeReference,在知道具体泛型类型的情况下可以实现反序列化,这里由于应用场景不适用不对其进行讨论。
如下场景:
public class PieChartVO<T extends BaseDebtVO> implements Serializable { private static final long serialVersionUID = -6422895776727574355L; private BigDecimal avgYearRate; private ArrayList<T> transVOspublic BigDecimal getAvgYearRate() { return avgYearRate; } public void setAvgYearRate(BigDecimal avgYearRate) this.avgYearRate = avgYearRatepublic ArrayList> getTransVOsreturn transVOssetTransVOs(ArrayListtransVOs = transVOs} }
CreditorDebtVO extends BaseDebtVO 254172337494852158Lprivate BigDecimal totalEarninggetTotalEarningreturn totalEarningsetTotalEarning(BigDecimal totalEarningtotalEarning = totalEarning} ObligorDebtVO { = 3314361571700869005L; private Integer overdueCountprivate BigDecimal overdueOtherFeepublic Integer getOverdueCount{ return overdueCount; } setOverdueCount(Integer overdueCountoverdueCount = overdueCountgetOverdueOtherFeereturn overdueOtherFeesetOverdueOtherFee(BigDecimal overdueOtherFeeoverdueOtherFee = overdueOtherFee}
{ "body": { "avgYearRate": 14.8, "transVOs"[ { "avgRate"19.2"cleanCount": 8"id"15"subTitle": "aaa""title""bbb""totalEarning"20.75"totalPrincipal"17000"transCount"3"transMoney"4698.93"transOverdueMoney"0 } ] }, "result"1 }
对于获取到的json数据并不知道具体的泛型类型,也就没法指定的情况下,解决方案是对反序列化进行自定义定制,fastJson自身对基础的field内置了许多反序列化器,当对json反序列化时,会根据filed的class找到相应的反序列化器来执行反序列化。
ParserConfig final IdentityHashMap<TypeObjectDeserializer> deserializers = new IdentityHashMap>(); /**省略了其他代码*/ private initDeserializers{ deserializersput(SimpleDateFormatclassMiscCodecinstance); deserializers(javasqlTimestampsqlDateDeserializerinstance_timestampDateTimeTimeDeserializerutilDateCodec(CalendarCalendarCodec(XMLGregorianCalendar); deserializers(JSONObjectMapDeserializer(JSONArrayCollectionCodec(Map(HashMap(LinkedHashMap(TreeMap(ConcurrentMap(ConcurrentHashMap(Collection(List(ObjectJavaObjectDeserializer(StringStringCodec(StringBuffer(StringBuilder(charCharacterCodec(CharacterbyteNumberDeserializer(Byteshort(ShortintIntegerCodec(IntegerlongLongCodec(Long(BigIntegerBigIntegerCodec(BigDecimalBigDecimalCodecfloatFloatCodec(Floatdouble(DoublebooleanBooleanCodec(Boolean(Class[].new CharArrayCodec()); deserializers(AtomicBoolean(AtomicInteger(AtomicLong(AtomicReferenceReferenceCodec(WeakReference(SoftReference(UUID(TimeZone(Locale(Currency(InetAddress(Inet4Address(Inet6Address(InetSocketAddress(File(URI(URL(Pattern(Charset(JSONPath(Number(AtomicIntegerArrayAtomicCodec(AtomicLongArray(StackTraceElementStackTraceElementDeserializer(Serializable(Cloneable(Comparable(Closeable(JSONPObjectnew JSONPDeserializer()); public ObjectDeserializer getDeserializer<?> clazzType type{ /** 首先从内部已经注册查找特定type的反序列化实例 */ ObjectDeserializer derializer = deserializersget(type); if (derializer != null{ return derializer; } ....... }
可以看到对于ArrayList的默认的反序列化器是CollectionCodec,另外fastjson还提供了@JSONField注解对field可以有一些自定义的处理,其deserializeUsing属性可以指定具体的反序列化器。我们要做的就很简单了。
自定义反序列化器实现CollectionCodec,具体的反序列化工作仍然交由CollectionCodec处理,只不过须要对得到的对象进行自定义的加工。这里通过判断某个field是否存在来决定以哪个类来反序列化。
DebtVODeserializer extends CollectionCodec { @Override public > T deserialze(DefaultJSONParser parserObject fieldName{ T list = superdeserialze(parsertypefieldName); JSONArray jsonArray = JSONparseArray(JSONtoJSONString(list)); ArrayList<CreditorDebtVO> debtVOs new ArrayList<>(); (jsonArray null && jsonArraysize()>0){ (jsonArraygetJSONObject().()!=){ ArrayList> creditorDebtVOList >)JSON),CreditorDebtVO); return (T)creditorDebtVOList; } else "overdueOtherFee"<ObligorDebtVO> obligorDebtVOList ObligorDebtVO)obligorDebtVOListelse return list} )debtVOs}
@JSONField(deserializeUsing = DebtVODeserializer) PieChartVO vo parSEObject(jsonPieChartVO);
如上,直接反序列化即可,对于使用方而言,不需要判断用哪个类来反序列化,代码上看简洁了许多...