问题
1.fastjson value 为null key 会丢失问题
2.SerializerFeature 配置参数
背景
和第三方系统进行对接,两边商量好了接口定义,有些是非必填项。从数据库查询出来的数据赋值给相应的key,有些String类型的 字段 查询语句里面没有对应的字段,默认是null。导致传过去的参数里面 value 为null 的key 都丢失
错误示例
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("ceshi", "12131231123");
jsonObject.put("ceshi1", null);
System.out.println("jsonObject.toJSONString() = " + jsonObject.toJSONString());
}
运行结果
jsonObject.toJSONString() = {"ceshi":"12131231123"}
小结
上面运行结果 key 为 ceshi1 的value 出现了丢失现象,这样导致对接方存在数据结构不完整的情况。等一系列的问题
解决方案
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("ceshi", "12131231123");
jsonObject.put("ceshi1", null);
System.out.println("jsonObject.toJSONString() = " + JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue));
}
运行结果
jsonObject.toJSONString() = {"ceshi":"12131231123","ceshi1":null}
小结
增加 SerializerFeature.WriteMapNullValue 这样子可以是 value 为null 的也可以正确输出
拓展
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("ceshi", "12131231123");
jsonObject.put("枚举", PodToolEnum.DGP.getCode());
jsonObject.put("时间", new Date());
jsonObject.put("转义", "\t");
List jihe = null;
Integer num = null;
Boolean flag = null;
jsonObject.put("集合", jihe);
jsonObject.put("数值", num);
jsonObject.put("ceshi1", null);
jsonObject.put("布尔", flag);
System.out.println("jsonObject.toJSONString() = " + JSON.toJSONString(jsonObject, SerializerFeature.UseSingleQuotes
, SerializerFeature.UseISO8601DateFormat
, SerializerFeature.PrettyFormat
, SerializerFeature.WriteTabAsSpecial
, SerializerFeature.WriteMapNullValue
, SerializerFeature.WriteNullNumberAsZero
, SerializerFeature.WriteNullListAsEmpty
, SerializerFeature.WriteNullStringAsEmpty
, SerializerFeature.WriteNullBooleanAsFalse
, SerializerFeature.SortField));
}
运行结果
jsonObject.toJSONString() = {
'ceshi':'12131231123',
'集合':null,
'数值':null,
'时间':'2023-01-31T10:00:01.895+08:00',
'枚举':'5',
'布尔':null,
'ceshi1':null,
'转义':'\t'
}
小结
上面 WriteNullNumberAsZero 、 WriteNullListAsEmpty 、WriteNullStringAsEmpty、WriteNullBooleanAsFalse 这几个配置项没有生效。
解决方案
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("ceshi", "12131231123");
jsonObject.put("枚举", PodToolEnum.DGP.getCode());
jsonObject.put("时间", new Date());
jsonObject.put("转义", "\t");
List jihe = null;
Integer num = null;
Boolean flag = null;
jsonObject.put("集合", jihe);
jsonObject.put("数值", num);
jsonObject.put("ceshi1", null);
jsonObject.put("布尔", flag);
ValueFilter filter = new ValueFilter() {
@Override
public Object process(Object obj, String s, Object v) {
if (v == null) {
return "";
}
return v;
}
};
System.out.println("jsonObject.toJSONString() = " + JSON.toJSONString(jsonObject,filter));
}
运行结果
jsonObject.toJSONString() = {"ceshi":"12131231123","集合":"","数值":"","时间":1675130844125,"枚举":"5","布尔":"","ceshi1":"","转义":"\t"}
小结
fastjson 里面提供了一个过滤器的功能,可以自定义value key 的重写功能
参考资料
fastjson:SerializerFeature属性使用
过滤器功能