190412-FastJson序列化对象中非字符串类型key输出非标准格式json串问题记录

文章目录
  1. 1. 问题复现
  2. 2. 兼容方案
  • II. 其他
    1. 1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
    2. 2. 声明
    3. 3. 扫描关注
  • 采用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

    评论

    Your browser is out-of-date!

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

    ×