这周前几天,同事问我,使用Fastjson进行Json的处理,需要转成Json的对象中还有null值,输出成JsonString后,该值和所对应的key都没有了。他的代码是这样的:

Map<String, String> map = new HashMap<String, String>();
map.put("a", "12");
map.put("b", null);
String jsonString = JSONObject.toJSONString(map);
System.out.println(jsonString);

输出为:

{"a":"12"}

b的key没了,value也没了,而对于使用该接口的下游系统来说,有key而value为null与无key是完全不同的概念,所以需要下发该key。

我搜了下,网上有提供方案,使用SerializerFeature.WriteMapNullValue。如下:

Map<String, String> map = new HashMap<String, String>();
map.put("a", "12");
map.put("b", null);
String jsonString = JSONObject.toJSONString(map,
        SerializerFeature.WriteMapNullValue);
System.out.println(jsonString);

输出为:

{"b":null,"a":"12"}


将null值直接输出成null了。源码在com.alibaba.fastjson.serializer.MapSerializer的write方法中,关键地方如下:

for (Map.Entry entry : map.entrySet()) {
    Object value = entry.getValue();
    Object entryKey = entry.getKey();
    // ......
    if (value == null) {
        if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) {
            continue; // 如果没有WriteMapNullValue直接退出本次循环,不进行处理
        }
    }
    // ......
    if (value == null) {
        out.writeNull();// 直接输出null
        continue;
    }
    // ......
}

但是输出null可能并不是下游系统希望的,他们可能希望给一个空字符串来表示。那么采用ValueFilter可以实现这个:

ValueFilter filter = new ValueFilter() {
    @Override
    public Object process(Object object, String name, Object value) {
        if (value == null)
            return ""; // 如果值为null,返回空字符串
        else
            return value;
    }
};

Map<String, String> map = new HashMap<String, String>();
map.put("a", "12");
map.put("b", null);
String jsonString = JSONObject.toJSONString(map, filter);
System.out.println(jsonString);

输出为:

{"b":"","a":"12"}

这样就达到目的了,科科

标签: Java, Fastjson

添加新评论