在使用alibaba的fastjson做json序列化时,由于上游系统对于json的要求过于严格,
才发现了JSON.toJSONString使用时值为NULL的属性被忽略的问题。
如果某个属性的值为null,再被序列化为字符串是默认会被忽略,原因和解决方式详述如下,
1,原因:
public static String toJSONString(Object object, SerializerFeature… features):
该方法将实体对象转换成Json字符串时,如果不传递参数SerializerFeature.WriteMapNullValue,则忽略值为null的属性。
转json串,默认设置了许多序列化配置:
名称 | 含义 |
QuoteFieldNames | 输出key时是否使用双引号,默认为true |
UseSingleQuotes | 使用单引号而不是双引号,默认为false |
WriteMapNullValue | 是否输出值为null的字段,默认为false |
WriteEnumUsingToString | Enum输出name()或者original,默认为false |
UseISO8601DateFormat | Date使用ISO8601格式输出,默认为false |
WriteNullListAsEmpty | List字段如果为null,输出为[],而非null |
WriteNullStringAsEmpty | 字符类型字段如果为null,输出为”“,而非null |
WriteNullNumberAsZero | 数值字段如果为null,输出为0,而非null |
WriteNullBooleanAsFalse | Boolean字段如果为null,输出为false,而非null |
SkipTransientField | 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true |
SortField | 按字段名称排序后输出。默认为false |
WriteTabAsSpecial | 把\t做转义输出,默认为false |
PrettyFormat | 结果是否格式化,默认为false |
WriteClassName | 序列化时写入类型信息,默认为false。反序列化是需用到 |
DisableCircularReferenceDetect | 消除对同一对象循环引用的问题,默认为false |
WriteSlashAsSpecial | 对斜杠’/’进行转义 |
BrowserCompatible | 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false |
WriteDateUseDateFormat | 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat); |
DisableCheckSpecialChar | 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false |
NotWriteRootClassName | 不知道 |
BeanToArray | 将对象转为array输出 |
WriteNonStringKeyAsString | 不是String的字段写为String |
NotWriteDefaultValue | 不设默认值 |
BrowserSecure | 不知道 |
IgnoreNonFieldGetter | 忽略没有getter方法的属性 |
WriteEnumUsingName |
目前版本的fastjson默认对enum对象使用WriteEnumUsingName属性,因此会将enum值序列化为其Name。 |
2.解决方式
加SerializerFeature.WriteMapNullValue即可,具体如下:
String ret = JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
引申阅读,大佬详细的程序展示,转载自:https://blog.csdn.net/weixin_44516305/article/details/88821815
1 背景
在Java开发中,通常需要将一个实体对象转换成Json字符串,使用FastJson来实现这种转换十分方便,只要使用FastJson中JSONObject静态类提供的toJSONString()静态方法即可。但是在转换时,我们可能需要指定使用实体对象的某些属性来进行转换,或者指定转换时要排除实体对象的某些属性。
FastJson提供的SerializeFilter类就可以实现这种需求,可以指定转换时要包含的属性,或者指定转换时要排除的属性。
JSONObject.toJSONString()默认忽略值为null的属性这篇文章分析了JSONObject.toJSONString()将实体对象转换成JSON字符串时默认是忽略值为null的属性,以及如何设置包含值为null的属性。本文则主要是演示使用SerializeFilter来指定包含或者排除的属性,使得生成的JSON字符串中包含或者不包含某些属性。
2 演示程序
2.1 此程序演示了使用JSONObject提供的以下方法将实体对象转换成Json字符串:
public static String toJSONString(Object object, SerializeFilter filter, SerializerFeature... features);
2.2 Java程序完整代码如下:
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
/**
* 使用FastJson将实体对象转换成Json字符串测试类
*/
public class FastJsonApplication {
public static void main(String[] args) {
User user = new User();
user.setId(1L);
user.setUsername("张三");
user.setPassword("");
user.setMobile(null);
user.setCountry("中国");
user.setCity("武汉");
String jsonUser = null;
/**
* 指定排除属性过滤器和包含属性过滤器
* 指定排除属性过滤器:转换成JSON字符串时,排除哪些属性
* 指定包含属性过滤器:转换成JSON字符串时,包含哪些属性
*/
String[] excludeProperties = {"country", "city"};
String[] includeProperties = {"id", "username", "mobile"};
PropertyPreFilters filters = new PropertyPreFilters();
PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();
excludefilter.addExcludes(excludeProperties);
PropertyPreFilters.MySimplePropertyPreFilter includefilter = filters.addFilter();
includefilter.addIncludes(includeProperties);
/**
* 情况一:默认忽略值为null的属性
*/
jsonUser = JSONObject.toJSONString(user, SerializerFeature.PrettyFormat);
System.out.println("情况一:\n" + jsonUser);
/**
* 情况二:包含值为null的属性
*/
jsonUser = JSONObject.toJSONString(user, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue);
System.out.println("情况二:\n" + jsonUser);
/**
* 情况三:默认忽略值为null的属性,但是排除country和city这两个属性
*/
jsonUser = JSONObject.toJSONString(user, excludefilter, SerializerFeature.PrettyFormat);
System.out.println("情况三:\n" + jsonUser);
/**
* 情况四:包含值为null的属性,但是排除country和city这两个属性
*/
jsonUser = JSONObject.toJSONString(user, excludefilter, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue);
System.out.println("情况四:\n" + jsonUser);
/**
* 情况五:默认忽略值为null的属性,但是包含id、username和mobile这三个属性
*/
jsonUser = JSONObject.toJSONString(user, includefilter, SerializerFeature.PrettyFormat);
System.out.println("情况五:\n" + jsonUser);
/**
* 情况六:包含值为null的属性,但是包含id、username和mobile这三个属性
*/
jsonUser = JSONObject.toJSONString(user, includefilter, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue);
System.out.println("情况六:\n" + jsonUser);
}
/**
* 用户实体类
*/
public static class User {
private Long id;
private String username;