Gson序列化输出Ignore策略 -- Map篇

简介: 前面介绍了几种gson在序列化时,忽略某些字段数输出的方式,然而当时的实例中,需要序列化的对象都是Java bean对象,如果我们需要序列化的是Map对象,又可以怎么处理呢?接下来我们通过实际的case,来演示如何实现Map忽略指定key的功能

前面介绍了几种gson在序列化时,忽略某些字段数输出的方式,然而当时的实例中,需要序列化的对象都是Java bean对象,如果我们需要序列化的是Map对象,又可以怎么处理呢?


接下来我们通过实际的case,来演示如何实现Map忽略指定key的功能


这里主要用到的知识点是Gson提供的扩展TypeAdapter,通过自定义的适配器,来实现自定义的序列化/反序列化,如我们需要实现的逻辑如下


public static class IgnoreMapTypeAdapter extends TypeAdapter<HashMap> {
    @Override
    public void write(JsonWriter out, HashMap value) throws IOException {
        Set<Map.Entry<Object, Object>> set = value.entrySet();
        out.beginObject();
        for (Map.Entry<Object, Object> entry : set) {
            // 在序列化输出时,忽略 key = pwd 的kv
            String strKey = String.valueOf(entry.getKey());
            if (strKey.equalsIgnoreCase("pwd")) {
                continue;
            }
            out.name(strKey);
            Object v = entry.getValue();
            if (v instanceof String) {
                out.value((String) v);
            } else if (v instanceof Number) {
                out.value((Number) v);
            } else if (v instanceof Boolean) {
                out.value((Boolean) v);
            } else {
                out.value(getGson().toJson(entry.getValue()));
            }
        }
        out.endObject();
    }
    @Override
    public HashMap read(JsonReader in) throws IOException {
      // 这里直接使用标准的gson进行反序列化
        Gson gson = new Gson();
        return gson.fromJson(in, HashMap.class);
    }
}
复制代码


注意上面实现逻辑中的write方法,遍历map,这里默认将所有的key都当成String格式,内部的实现主要是基于gson的流式序列化策略来完成的(JsonWrite流式序列化,下篇博文介绍)


其次对于value的输出,这里做了简单的适配,如果是非基础类型,这里并没有使用普通的Gson进行转换,而是借助了递归的思路,关键点在于 etGson()的实现逻辑

private static Gson getGson() {
    return new GsonBuilder().registerTypeAdapter(HashMap.class, new IgnoreMapTypeAdapter()).create();
}
复制代码


接下来写个简单的case验证一下

private static Map<String, Object> newMap(String key, Object val, Object... kv) {
    Map<String, Object> ans = new HashMap<>(8);
    ans.put(key, val);
    for (int i = 0, size = kv.length; i < size; i += 2) {
        ans.put(String.valueOf(kv[i]), kv[i + 1]);
    }
    return ans;
}
@Test
public void testCase() {
    Gson gson = getGson();
    Map map = newMap("user", "yihui", "pwd", 123455, "sub", newMap("key", "lll", "v", 1234L, "pwd", "abc"), "list", Arrays.asList(1, 2, 3));
    String str = gson.toJson(map);
    System.out.println(str);
    System.out.println(new Gson().toJson(map));
}
复制代码


输出结果如下

{"sub":"{\"key\":\"lll\",\"v\":1234}","list":"[1,2,3]","user":"yihui"}
{"sub":{"pwd":"abc","key":"lll","v":1234},"pwd":123455,"list":[1,2,3],"user":"yihui"}
复制代码


注意查看上面的实现,第一行是忽略了pwd的json串,第二行则是普通的Gson输出的json串;虽然第一个满足了我们的需求,但是sub的value从object变成了String,这个和我们的预期的不太一致,接下来,下一篇博文流式序列化将带来解决方案



相关文章
|
7月前
|
JSON Java API
GSON 泛型对象反序列化解决方案
GSON 泛型对象反序列化解决方案
343 0
|
7月前
|
JSON 数据格式
使用 Gson 将 Map、List等转换为json string
使用 Gson 将 Map、List等转换为json string
191 0
|
7月前
|
JSON Android开发 数据格式
android 使用GSON 序列化对象出现字段被优化问题解决方案
android 使用GSON 序列化对象出现字段被优化问题解决方案
132 0
|
Android开发
Android 中使用Gson进行list集合的序列化与反序列化
Android 中使用Gson进行list集合的序列化与反序列化
197 0
|
JSON Java API
Android 中使用Gson完成对象的序列化与反序列化
Android 中使用Gson完成对象的序列化与反序列化
261 0
|
Dubbo Java 应用服务中间件
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
239 0
|
JSON 缓存 Java
Android 序列化框架 Gson 原理分析,可以优化吗?
Gson 是 Google 推出的 Java Json 解析库,具有接入成本低、使用便捷、功能扩展性良好等优点,想必大家都很熟悉了。在这篇文章里,我们将讨论 Gson 的基本用法和以及主要流程的源码分析。
358 0
|
机器学习/深度学习 JSON 网络协议
结构体 map 切片序列化|学习笔记
快速学习结构体 map 切片序列化
|
JSON 数据格式
Gson流式反序列化JsonReader
前面介绍了一片Gson的流式序列化,接下来我们看一下流式的反序列化,主要借助JsonReader来实现
323 0
|
JSON 数据格式
Gson流式序列化JsonWriter
通常我们序列化使用时,是直接使用Gson将整个对象转换为Json串,如果有看过gson源码的小伙伴会发现其内部实际上是基于JsonWriter来实现流式序列化的 接下来我们来看一下JsonWriter的使用姿势
657 0