登录
注册
写文章
发现
工具
fastjson的toJSONString序列化
_3t3lfz KEKfID
编辑文章
fastjson的toJSONString序列化
asfx站长
2021.04.16 10:52:31
阅读
1384
#### com.alibaba.fastjson.JSON.toJSONString使用时值为NULL的属性被忽略的问题 在使用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。 使用WriteEnumUsingToString方法可以序列化时将Enum转换为toString()的返回值;同时override toString函数能够将enum值输出需要的形式。但是这样做会带来一个问题,对应的反序列化使用的Enum的静态方法valueof可能无法识别自行生成的toString(),导致反序列化出错。 如果将节省enum序列化后的大小,可以将enum序列化其ordinal值,保存为int类型。fastJson在反序列化时,如果值为int,则能够使用ordinal值匹配,找到合适的对象。 fastjson要将enum序列化为ordinal只需要禁止WriteEnumUsingName feature。 首先根据默认的features排除WriteEnumUsingName,然后使用新的features序列化即可。 ###### 测试例子: ``` import lombok.Data; @Data public class TestUserHobby { private Long id; private String like; private String extra; } ``` ``` import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.spring.PropertyPreFilters; import lombok.Data; import java.util.ArrayList; import java.util.Date; import java.util.List; @Data public class TestUser { private Long id; private String name; private Integer age; private Date birthDay; private List<TestUserHobby> hobbyList; private List<String> strList; public static void main(String[] args) { TestUser t = new TestUser(); // t.setName("xxx"); TestUserHobby hobby1 = new TestUserHobby(); hobby1.setId(1L); hobby1.setLike("aa"); List<TestUserHobby> hobbyList = new ArrayList<>(); hobbyList.add(hobby1); t.setHobbyList(hobbyList); /** * 指定排除属性过滤器和包含属性过滤器 * 指定排除属性过滤器:转换成JSON字符串时,排除哪些属性 * 指定包含属性过滤器:转换成JSON字符串时,包含哪些属性 */ String[] excludeProperties = {"id", "age"}; String[] includeProperties = {"id", "name", "hobbyList", "like", "extra"}; toJSONString(t, null, includeProperties); } /** * json序列化 * @param target * @param excludeProperties * @param includeProperties */ private static void toJSONString(Object target, String[] excludeProperties, String[] includeProperties){ PropertyPreFilters filters = new PropertyPreFilters(); PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter(); // 排除属性 PropertyPreFilters.MySimplePropertyPreFilter includeFilter = filters.addFilter(); // 包含属性 if(excludeProperties != null){ excludeFilter.addExcludes(excludeProperties); } if(includeProperties != null){ includeFilter.addIncludes(includeProperties); } SerializeFilter[] serializeFilters = {excludeFilter, includeFilter}; String jsonString = JSON.toJSONString(target , serializeFilters // 过滤器 , SerializerFeature.WriteMapNullValue // 输出值为null的字段 , SerializerFeature.WriteNullListAsEmpty // 为null的List输出为[] , SerializerFeature.WriteNullStringAsEmpty // 为null的String输出为"" ); System.out.println(jsonString); } } ```
我的主页
退出