FastJson对复杂的泛型对象的解析问题

前端之家收集整理的这篇文章主要介绍了FastJson对复杂的泛型对象的解析问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

首先要说的是FastJson提供了一个用于处理泛型反序列化的类TypeReference,在知道具体泛型类型的情况下可以实现反序列化,这里由于应用场景不适用不对其进行讨论。

如下场景:

  1. public class PieChartVO<T extends BaseDebtVO> implements Serializable {
  2.  
  3. private static final long serialVersionUID = -6422895776727574355L;
  4.  
  5. private BigDecimal avgYearRate;
  6. private ArrayList<T> transVOspublic BigDecimal getAvgYearRate() {
  7. return avgYearRate;
  8. }
  9.  
  10. public void setAvgYearRate(BigDecimal avgYearRate) this.avgYearRate = avgYearRatepublic ArrayList> getTransVOsreturn transVOssetTransVOs(ArrayListtransVOs = transVOs}
  11. }
  1. CreditorDebtVO extends BaseDebtVO 254172337494852158Lprivate BigDecimal totalEarninggetTotalEarningreturn totalEarningsetTotalEarning(BigDecimal totalEarningtotalEarning = totalEarning}
  2.  
  3. ObligorDebtVO {
  4.  
  5. = 3314361571700869005L;
  6.  
  7. private Integer overdueCountprivate BigDecimal overdueOtherFeepublic Integer getOverdueCount{
  8. return overdueCount;
  9. }
  10.  
  11. setOverdueCount(Integer overdueCountoverdueCount = overdueCountgetOverdueOtherFeereturn overdueOtherFeesetOverdueOtherFee(BigDecimal overdueOtherFeeoverdueOtherFee = overdueOtherFee}
  1. {
  2. "body": {
  3. "avgYearRate": 14.8,
  4. "transVOs"[
  5. {
  6. "avgRate"19.2"cleanCount": 8"id"15"subTitle": "aaa""title""bbb""totalEarning"20.75"totalPrincipal"17000"transCount"3"transMoney"4698.93"transOverdueMoney"0
  7. }
  8. ]
  9. },
  10. "result"1
  11. }

对于获取到的json数据并不知道具体的泛型类型,也就没法指定的情况下,解决方案是对反序列化进行自定义定制,fastJson自身对基础的field内置了许多反序列化器,当对json反序列化时,会根据filed的class找到相应的反序列化器来执行反序列化。

  1. ParserConfig final IdentityHashMap<TypeObjectDeserializer> deserializers = new IdentityHashMap>();
  2.  
  3. /**省略了其他代码*/
  4. private initDeserializers{
  5. deserializersput(SimpleDateFormatclassMiscCodecinstance);
  6. deserializers(javasqlTimestampsqlDateDeserializerinstance_timestampDateTimeTimeDeserializerutilDateCodec(CalendarCalendarCodec(XMLGregorianCalendar);
  7.  
  8. 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());
  9.  
  10. 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());
  11. public ObjectDeserializer getDeserializer<?> clazzType type{
  12. /** 首先从内部已经注册查找特定type的反序列化实例 */
  13. ObjectDeserializer derializer = deserializersget(type);
  14. if (derializer != null{
  15. return derializer;
  16. }
  17. .......
  18. }

可以看到对于ArrayList的默认的反序列化器是CollectionCodec,另外fastjson还提供了@JSONField注解对field可以有一些自定义的处理,其deserializeUsing属性可以指定具体的反序列化器。我们要做的就很简单了。

自定义反序列化器实现CollectionCodec,具体的反序列化工作仍然交由CollectionCodec处理,只不过须要对得到的对象进行自定义的加工。这里通过判断某个field是否存在来决定以哪个类来反序列化。

  1. DebtVODeserializer extends CollectionCodec {
  2. @Override
  3. public > T deserialze(DefaultJSONParser parserObject fieldName{
  4. T list = superdeserialze(parsertypefieldName);
  5. JSONArray jsonArray = JSONparseArray(JSONtoJSONString(list));
  6. ArrayList<CreditorDebtVO> debtVOs new ArrayList<>();
  7. (jsonArray null && jsonArraysize()>0){
  8. (jsonArraygetJSONObject().()!=){
  9. ArrayList> creditorDebtVOList >)JSON),CreditorDebtVO);
  10. return (T)creditorDebtVOList;
  11. } else "overdueOtherFee"<ObligorDebtVO> obligorDebtVOList ObligorDebtVO)obligorDebtVOListelse return list}
  12.  
  13. )debtVOs}

修改PieChartVO,指定自定义的反序列化器

  1. @JSONField(deserializeUsing = DebtVODeserializer)
  2. PieChartVO vo parSEObject(jsonPieChartVO);

如上,直接反序列化即可,对于使用方而言,不需要判断用哪个类来反序列化,代码上看简洁了许多...

猜你在找的Json相关文章