采用fastjson作为项目的json序列化和反序列化工具,遇到一个蛋疼至极的问题, 如Map,key为int,则输出的字符串中,key没有被双引号括起来,导致前端解析失败

1. 问题复现

环境相关

1
2
3
4
5
6
7
8
jdb1.8


<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.45</version>
</dependency>

测试case

1
2
3
4
5
6
7
8
9
10
11
@Test
public void testJson() {
Map<Integer, String> ans = new HashMap<>();
ans.put(10, "hello");
ans.put(20, "world");

System.out.println("fastjson: " + JSON.toJSONString(ans));

Gson gson = new Gson();
System.out.println("gson: " + gson.toJson(ans));
}

为了对比,把gson也加进来了,输出结果如下

1
2
fastjson: {20:"world",10:"hello"}
gson: {"20":"world","10":"hello"}

针对fastjson的输出,js的序列化直接异常

IMAGE

2. 兼容方案

既然fastjson有这个问题,那有必要看一下有没有使用方式来避免这个问题了,看一下fastjson的常用序列化方法

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
/**
* This method serializes the specified object into its equivalent Json representation. Note that this method works fine if the any of the object fields are of generic type,
* just the object itself should not be of a generic type. If you want to write out the object to a
* {@link Writer}, use {@link #writeJSONString(Writer, Object, SerializerFeature[])} instead.
*
* @param object the object for which json representation is to be created setting for fastjson
* @return Json representation of {@code object}.
*/
public static String toJSONString(Object object) {
return toJSONString(object, emptyFilters);
}

public static String toJSONString(Object object, SerializerFeature... features) {
return toJSONString(object, DEFAULT_GENERATE_FEATURE, features);
}

/**
* @since 1.2.11
*/
public static String toJSONString(Object object, int defaultFeatures, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter((Writer) null, defaultFeatures, features);

try {
JSONSerializer serializer = new JSONSerializer(out);
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}

我们常用的是上面的第一个方法,看到上面的第二个方法,自然可以想到,是不是可以通过传参来设置序列化的一些属性, SerializerFeature 是一个枚举,进去查看,会找到一些有意思的参数,如SerializerFeature.WriteNonStringKeyAsString将非字符串的key装换为String

1
2
3
4
5
6
7
8
9
10
@Test
public void testJson() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "hello");
map.put(2, "world");
System.out.println(JSON.toJSONString(map));

// 如果key不是字符串,则序列化为字符串
System.out.println(JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString));
}

输出结果如下

IMAGE

II. 其他

1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

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

3. 扫描关注

一灰灰blog

QrCode

知识星球

goals