加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 19:48:07 所属栏目:百科 来源:网络整理
导读:首先要说的是FastJson 提供了一个用于处理泛型反序列化的类 TypeReference,在知道具体泛型类型的情况下可以实现反序列化,这里由于应用场景不适用不对其进行讨论。 如下场景: public class PieChartVO T extends BaseDebtVO implements Serializable { priv

首先要说的是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}

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读