最近项目中遇到了两个 Json 解析的坑,一个是后端没有按照约定返回对应类型的字段,文档说明写了 int ,但是它直接返回了 String 类型;另外一个数据请求成功后, data 是一个 Object 类型,但是如果数据请求失败,后端直接返回了 List
因为这两个坑,后端周末紧急加班去发版本, 不过就勾起了我对 Gson 容错的方案思考
Gson 源码的分析
要解决业务方的需求,客户端这边想法子做一定的 Json 容错,那么就必须去了解一下 Gson 的源码了
先看下 Gson 的日常用法:
Gson gson = new Gson();
//反序列化得到数据bean
DataBean data = gson.fromJson(jsonString,DataBean.class);
Gson 是如何将 Json 反序列化的?答案是通过 TypeAdapter
关于
TypeAdapter
,可以看一下这篇文章:你真的会用Gson吗? 整个系列看完,Gson的基本用法就都掌握了
Gson 内部实现了大量的 TypeAdapter
,在其构造方法里面,就将全部的 TypeAdapter
存储起来:
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded) {
//省去部分代码
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);
//重点:添加自定义的 TypeAdapter
factories.addAll(factoriesToBeAdded);
// type adapters for basic platform types
factories.add(TypeAdapters.STRING_FACTORY);
factories.add(TypeAdapters.INTEGER_FACTORY);
factories.add(TypeAdapters.BOOLEAN_FACTORY);
factories.add(TypeAdapters.BYTE_FACTORY);
factories.add(TypeAdapters.SHORT_FACTORY);
TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
factories.add(TypeAdapters.newFactory(double.class, Double.class,
doubleAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.newFactory(float.class, Float.class,
floatAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.NUMBER_FACTORY);
factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)))