2018-05-09

在写这篇文章时参考了以下两篇博客

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;
    }

}

4. 具体测试代码中列举了Boolean类型枚举、整型枚举、String类型枚举,可以自由通过各个枚举类的实现方式序列化与反序列化。

5.最后附上源代码下载地址,希望路过的多发表意见,顺便下载赚个积分。

https://download.csdn.net/download/mayuqing/10404104

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容