211029-Gson实现Map忽略指定key序列化输出策略

文章目录
  1. 一灰灰的联系方式

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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()的实现逻辑

1
2
3
private static Gson getGson() {
return new GsonBuilder().registerTypeAdapter(HashMap.class, new IgnoreMapTypeAdapter()).create();
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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));
}

输出结果如下

1
2
{"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,这个和我们的预期的不太一致,接下来,下一篇博文流式序列化将带来解决方案

一灰灰的联系方式

尽信书则不如无书,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

QrCode

# Gson

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×