在写这篇文章时参考了以下两篇博客
1.https://blog.csdn.net/RekaDowney/article/details/52292567?locationNum=14
2.https://blog.csdn.net/atm008/article/details/51733849
总结以下基本的方式就两种
1.基于JsonSerializer 和JsonDeserializer 接口来解决问题,在序列化与反序列化过程中重写,进行具体的转化过程。
优点不说了,缺点是需要在gson创建的时候注册很多枚举类,这样的前提是枚举类已经存在,对于未来不存在的枚举类无法做处理,对于顶层拦截框架处理json时就比较麻烦了,在顶层处理时,具体的枚举类应该是抽象的,不可见的,这样就可以处理未来任何的枚举类。
2. 对TypeAdapter的工厂类TypeAdapterFactory来解决该问题,但是该解决方案有个不足之处,那就是需要修改Gson的源码,这里就不讲该方案了,有需要的同学自行搜索。
这个处理方法优点是可以统一处理任何枚举类,但唯一的缺点是需要修改源代码,修改源代码这个个人不建议,因为组件面临持久更新、组件之间重复依赖无法不好处理冲突。
3. 基于以上两篇博客代码,个人做了处理,确实花费了些时间,不过觉得值得,大家可以认为是第三种方案(改造第一种方案)
优点:
1.可以统一处理任何枚举类,不需要修改gson源代码。
缺点:
1.对于在实体中申明枚举类成员变量方式有点改变
2.代码中存在反射过程,个人人觉得反射有降低效率的问题。
具体代码如下
1.枚举类接口GsonEnum
public interface GsonEnum {
Object serialize();
E deserialize(JsonElement jsonEnum);
E get();
}
2.序列化转换器GsonEnumTypeAdapter
public class GsonEnumTypeAdapter<E> implements JsonSerializer<E>, JsonDeserializer<E> {
public GsonEnumTypeAdapter() {
}
@Override
public JsonElement serialize(E src, Type typeOfSrc, JsonSerializationContext context) {
JsonPrimitive jsonElement = null;
if (null != src && src instanceof GsonEnum) {
try {
Constructor<JsonPrimitive> constructor = JsonPrimitive.class.getDeclaredConstructor(Object.class);
constructor.setAccessible(true);
jsonElement = constructor.newInstance(((GsonEnum) src).serialize());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return jsonElement;
}
@Override
public E deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
Type[] argumentsTypes = ((ParameterizedType) type).getActualTypeArguments();
if (rawType instanceof Class && GsonEnum.class.isAssignableFrom((Class) rawType)) {
try {
Type argType = argumentsTypes.length > 0 ? argumentsTypes[0] : null;
if (argType != null) {
GsonEnum[] objs = (GsonEnum[]) ((Class) argType).getEnumConstants();
if (objs != null && objs.length > 0) {
return (E) objs[0].deserialize(json);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
}