首先要说的是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);
如上,直接反序列化即可,对于使用方而言,不需要判断用哪个类来反序列化,代码上看简洁了许多...