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

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

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

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

原文链接:https://www.f2er.com/json/288568.html

猜你在找的Json相关文章