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

2024-06-11 05:48

本文主要是介绍FastJson对复杂的泛型对象的解析问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

如下场景:

public class PieChartVO<T extends BaseDebtVO> implements Serializable {private static final long serialVersionUID = -6422895776727574355L;private BigDecimal avgYearRate;private ArrayList<T> transVOs;public BigDecimal getAvgYearRate() {return avgYearRate;}public void setAvgYearRate(BigDecimal avgYearRate) {this.avgYearRate = avgYearRate;}public ArrayList<T> getTransVOs() {return transVOs;}public void setTransVOs(ArrayList<T> transVOs) {this.transVOs = transVOs;}
}
public class CreditorDebtVO extends BaseDebtVO {private static final long serialVersionUID = -254172337494852158L;private BigDecimal totalEarning;public BigDecimal getTotalEarning() {return totalEarning;}public void setTotalEarning(BigDecimal totalEarning) {this.totalEarning = totalEarning;}}
public class ObligorDebtVO extends BaseDebtVO {private static final long serialVersionUID = 3314361571700869005L;private Integer overdueCount;private BigDecimal overdueOtherFee;public Integer getOverdueCount() {return overdueCount;}public void setOverdueCount(Integer overdueCount) {this.overdueCount = overdueCount;}public BigDecimal getOverdueOtherFee() {return overdueOtherFee;}public void setOverdueOtherFee(BigDecimal overdueOtherFee) {this.overdueOtherFee = 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找到相应的反序列化器来执行反序列化。

public class ParserConfig {private final IdentityHashMap<Type, ObjectDeserializer> deserializers = new IdentityHashMap<Type, ObjectDeserializer>();/**省略了其他代码*/private void initDeserializers() {deserializers.put(SimpleDateFormat.class, MiscCodec.instance);deserializers.put(java.sql.Timestamp.class, SqlDateDeserializer.instance_timestamp);deserializers.put(java.sql.Date.class, SqlDateDeserializer.instance);deserializers.put(java.sql.Time.class, TimeDeserializer.instance);deserializers.put(java.util.Date.class, DateCodec.instance);deserializers.put(Calendar.class, CalendarCodec.instance);deserializers.put(XMLGregorianCalendar.class, CalendarCodec.instance);deserializers.put(JSONObject.class, MapDeserializer.instance);deserializers.put(JSONArray.class, CollectionCodec.instance);deserializers.put(Map.class, MapDeserializer.instance);deserializers.put(HashMap.class, MapDeserializer.instance);deserializers.put(LinkedHashMap.class, MapDeserializer.instance);deserializers.put(TreeMap.class, MapDeserializer.instance);deserializers.put(ConcurrentMap.class, MapDeserializer.instance);deserializers.put(ConcurrentHashMap.class, MapDeserializer.instance);deserializers.put(Collection.class, CollectionCodec.instance);deserializers.put(List.class, CollectionCodec.instance);deserializers.put(ArrayList.class, CollectionCodec.instance);deserializers.put(Object.class, JavaObjectDeserializer.instance);deserializers.put(String.class, StringCodec.instance);deserializers.put(StringBuffer.class, StringCodec.instance);deserializers.put(StringBuilder.class, StringCodec.instance);deserializers.put(char.class, CharacterCodec.instance);deserializers.put(Character.class, CharacterCodec.instance);deserializers.put(byte.class, NumberDeserializer.instance);deserializers.put(Byte.class, NumberDeserializer.instance);deserializers.put(short.class, NumberDeserializer.instance);deserializers.put(Short.class, NumberDeserializer.instance);deserializers.put(int.class, IntegerCodec.instance);deserializers.put(Integer.class, IntegerCodec.instance);deserializers.put(long.class, LongCodec.instance);deserializers.put(Long.class, LongCodec.instance);deserializers.put(BigInteger.class, BigIntegerCodec.instance);deserializers.put(BigDecimal.class, BigDecimalCodec.instance);deserializers.put(float.class, FloatCodec.instance);deserializers.put(Float.class, FloatCodec.instance);deserializers.put(double.class, NumberDeserializer.instance);deserializers.put(Double.class, NumberDeserializer.instance);deserializers.put(boolean.class, BooleanCodec.instance);deserializers.put(Boolean.class, BooleanCodec.instance);deserializers.put(Class.class, MiscCodec.instance);deserializers.put(char[].class, new CharArrayCodec());deserializers.put(AtomicBoolean.class, BooleanCodec.instance);deserializers.put(AtomicInteger.class, IntegerCodec.instance);deserializers.put(AtomicLong.class, LongCodec.instance);deserializers.put(AtomicReference.class, ReferenceCodec.instance);deserializers.put(WeakReference.class, ReferenceCodec.instance);deserializers.put(SoftReference.class, ReferenceCodec.instance);deserializers.put(UUID.class, MiscCodec.instance);deserializers.put(TimeZone.class, MiscCodec.instance);deserializers.put(Locale.class, MiscCodec.instance);deserializers.put(Currency.class, MiscCodec.instance);deserializers.put(InetAddress.class, MiscCodec.instance);deserializers.put(Inet4Address.class, MiscCodec.instance);deserializers.put(Inet6Address.class, MiscCodec.instance);deserializers.put(InetSocketAddress.class, MiscCodec.instance);deserializers.put(File.class, MiscCodec.instance);deserializers.put(URI.class, MiscCodec.instance);deserializers.put(URL.class, MiscCodec.instance);deserializers.put(Pattern.class, MiscCodec.instance);deserializers.put(Charset.class, MiscCodec.instance);deserializers.put(JSONPath.class, MiscCodec.instance);deserializers.put(Number.class, NumberDeserializer.instance);deserializers.put(AtomicIntegerArray.class, AtomicCodec.instance);deserializers.put(AtomicLongArray.class, AtomicCodec.instance);deserializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);deserializers.put(Serializable.class, JavaObjectDeserializer.instance);deserializers.put(Cloneable.class, JavaObjectDeserializer.instance);deserializers.put(Comparable.class, JavaObjectDeserializer.instance);deserializers.put(Closeable.class, JavaObjectDeserializer.instance);deserializers.put(JSONPObject.class, new JSONPDeserializer());}public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {/** 首先从内部已经注册查找特定type的反序列化实例 */ObjectDeserializer derializer = deserializers.get(type);if (derializer != null) {return derializer;}.......}}

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

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

public class DebtVODeserializer extends CollectionCodec {@Overridepublic <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {T list = super.deserialze(parser, type, fieldName);JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(list));ArrayList<CreditorDebtVO> debtVOs = new ArrayList<>();if (jsonArray != null && jsonArray.size()>0){if (jsonArray.getJSONObject(0).get("totalEarning")!=null){ArrayList<CreditorDebtVO> creditorDebtVOList = (ArrayList<CreditorDebtVO>)JSON.parseArray(JSON.toJSONString(list),CreditorDebtVO.class);return (T)creditorDebtVOList;} else if (jsonArray.getJSONObject(0).get("overdueOtherFee")!=null){ArrayList<ObligorDebtVO> obligorDebtVOList = (ArrayList<ObligorDebtVO>)JSON.parseArray(JSON.toJSONString(list),ObligorDebtVO.class);return (T)obligorDebtVOList;}} else {return list;}return (T)debtVOs;}
}

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

@JSONField(deserializeUsing = DebtVODeserializer.class)public void setTransVOs(ArrayList<T> transVOs) {this.transVOs = transVOs;}

PieChartVO vo = JSON.parseObject(json,PieChartVO.class);

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

这篇关于FastJson对复杂的泛型对象的解析问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1050348

相关文章

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以