[alibaba/fastjson]map序列化后仍使用int作为key

2025-10-31 239 views
0

环境

java version

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
OS: macOS 10.13.6 fastjson version: 1.2.49

Code

package moe.chigusa;

import com.alibaba.fastjson.JSON;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class FastJsonTest {
    @Test
    public void test() {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1, 1);
        map.put(2, 2);
        String json = JSON.toJSONString(map);
        System.out.println(json);
    }
}

Result

{1:1,2:2}

在json的语法规则中,不允许int作为key,需要序列化为以下的形式

{"1":1,"2":2}

回答

9

fastjson似乎希望能使用所有类型包括对象作为json的key,估计只能在应用时按需追加WriteNonStringKeyAsString使int被序列化为String. String json = JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString);

3

fastjson似乎希望能使用所有类型包括对象作为json的key,估计只能在应用时按需追加WriteNonStringKeyAsString使int被序列化为String. String json = JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString);

rfc7159 按照rfc的规定,key只应该是string,SerializerFeature.WriteNonStringKeyAsString应该默认就添加进去的吧

9

我尝试添加进去之后发现太多测试无法通过,包括各种以整型,长整型,null甚至是对象作为key的测试。所以我猜测这个项目比起规范化更注重原生态的序列化和反序列化,只能问问owner 是怎么想的了

1

fastjson似乎希望能使用所有类型包括对象作为json的key,估计只能在应用时按需追加WriteNonStringKeyAsString使int被序列化为String. String json = JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString);

rfc7159 按照rfc的规定,key只应该是string,SerializerFeature.WriteNonStringKeyAsString应该默认就添加进去的吧

我试验了下,对待key是一个属性名的没啥问题,但是在序列化 :

Map<UserDto,xxxx>  
这种数据类型的时候,如果你加上这个SerializerFeature.WriteNonStringKeyAsString 就会导致解析错误
7

fastjson似乎希望能使用所有类型包括对象作为json的key,估计只能在应用时按需追加WriteNonStringKeyAsString使int被序列化为String. String json = JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString);

rfc7159 按照rfc的规定,key只应该是string,SerializerFeature.WriteNonStringKeyAsString应该默认就添加进去的吧

我试验了下,对待key是一个属性名的没啥问题,但是在序列化 :

Map<UserDto,xxxx>  
这种数据类型的时候,如果你加上这个SerializerFeature.WriteNonStringKeyAsString 就会导致解析错误

验证代码如下:

@Data
@Accessors(chain = true)
public class UserDto {
    private int userId;
    private String userName;
    private Date birthday;
    private BigDecimal money;
    private int count;
    private int age;
    //get-set方法省略   
}

下面是测试方法:

static {
        //下面这行,注释上就正常,不注释点就报错
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNonStringKeyAsString.getMask();
    }

    @Test
    public void testJson() {
        Map<UserDto, Integer> data = new HashMap<>();
        data.put(new UserDto().setAge(12), 12);
        log.info("查看map序列化:{}", JSON.toJSONString(data));
        String result = JSON.toJSONString(data);
        HashMap<UserDto, Integer> parseResult = JSON.parseObject(result, new TypeReference<HashMap<UserDto, Integer>>() {

        });
        log.info("查看解析结果:{}!", parseResult);
    }

如果不注释就会报错:

com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 1, fastjson-version 1.2.62

    at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:505)
    at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:1555)
    at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_UserDto.deserialze(Unknown Source)
    at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:284)
    at com.alibaba.fastjson.parser.deserializer.MapDeserializer.parseMap(MapDeserializer.java:295)
    at com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:67)
    at com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:43)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:687)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:383)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:351)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:265)
0

看了下,新版本没问题了