一、FastJson简介
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
Fastjson 源码地址:https://github.com/alibaba/fastjson
Fastjson 中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN
二、Fastjson 特性
- 提供服务器端、安卓客户端两种解析工具,性能表现较好。
- 提供了 toJSONString() 和 parseObject() 方法来将 Java 对象与 JSON 相互转换。调用toJSONString方 法即可将对象转换成 JSON 字符串,parseObject 方法则反过来将 JSON 字符串转换成对象。
- 允许转换预先存在的无法修改的对象(只有class、无源代码)。
- Java泛型的广泛支持。
- 允许对象的自定义表示、允许自定义序列化类。
- 支持任意复杂对象(具有深厚的继承层次和广泛使用的泛型类型)
- …
三、下载和使用
你可以在 maven 中央仓库中直接下载:
https://repo1.maven.org/maven2/com/alibaba/fastjson/
或者配置 maven 依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>x.x.x</version></dependency>
其中 x.x.x 是版本号,根据需要使用特定版本,建议使用最新版本。
四、常见使用
4.1
@JSONField
使用fastjson进行需要对字段进行一些特殊处理,比如时间格式,前后端名字不一致,字段为null是否依然序列化等问题。那么fastjson的@JSONField就能很好的解决这些问题。
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER})public@interfaceJSONField{intordinal()default0;//是根据fieldName的字母序进行序列的,你可以通过ordinal指定字段的顺序Stringname()default"";//序列化和反序列化时候的别名Stringformat()default"";//用于字符串格式的日期转换booleanserialize()defaulttrue;// 是否参与序列化booleandeserialize()defaulttrue;//是否参与反序列化SerializerFeature[]serialzeFeatures()default{};//序列化选项 SerializerFeature.WriteNullNumberAsZero 如空Number填充0Feature[]parseFeatures()default{};//反序列化选项Stringlabel()default"";//标签,booleanjsonDirect()defaultfalse;//当你有⼀个字段是json字符串的数据,你希望直接输出,⽽不是经过转义之后再输出。Class<?>serializeUsing()defaultVoid.class;// 属性的序列化类,可定制。可有现存的,比如本来是Long,序列化的时候转为String:serializeUsing= ToStringSerializer.classClass<?>deserializeUsing()defaultVoid.class;// 属性的反序列化类,可定制。String[]alternateNames()default{};//参与反序列化时候的别名booleanunwrapped()defaultfalse;// 对象映射到父对象上。不进行子对象映射。简单而言,就是属性为对象的时候,属性对象里面的属性直接输出当做父对象的属性输出StringdefaultValue()default"";//设置默认值}
现在开始先介绍几个基本属性:ordinal 、name 、serialize、 deserialize、 format、defaultValue
/**
* @author xuyang.li
* @date 2022/12/3 11:56
* @description
*/@Data@Builder@AllArgsConstructor@NoArgsConstructorpublicclassPerson{@JSONField(ordinal =1)privateString name;@JSONField(name ="nation",defaultValue ="China",serialize =false)privateString country;@JSONField(ordinal =2,name ="old",deserialize =false)privateInteger age;@JSONField(name ="num",defaultValue ="0")privateInteger number;@JSONField(ordinal =3,format ="yyyy-MM-dd")privateDate birthday;}publicvoidtestJsonField(){Person person =Person.builder().name("张三").age(18).birthday(newDate()).build();String jsonStr =JSON.toJSONString(person);System.out.println(jsonStr);//{"num":"0","name":"张三","old":18,"birthday":"2022-12-03"}Person newPerson =JSON.parseObject(jsonStr,Person.class);System.out.println(JSON.toJSONString(newPerson));//{"num":0,"name":"张三","birthday":"2022-12-03"}}
4.2 serialzeFeatures、parseFeatures
他们是序列化、反序列化时候的一些可选的特征:
- 序列化的时候比如fastjson默认是不会将为null的属性输出的,若是我们也想输出,可以加入
@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue)
数值型为null的话,就输出0,可以使用@JSONField(serialzeFeatures = SerializerFeature.WriteNullNumberAsZero) - 反序列化的时候,比如parser是否将允许使用非双引号属性名字。@JSONField(parseFeatures = Feature.AllowSingleQuotes)
@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{privateString name;privateString dress;@JSONField(serialzeFeatures =SerializerFeature.WriteNullNumberAsZero)privateInteger num;@JSONField(serialzeFeatures =SerializerFeature.WriteMapNullValue)privateDate celebrateHoliday;}publicstaticvoidmain(String[] args){Nation nation =Nation.builder().name("汉族").build();String str =JSON.toJSONString(nation);System.out.println(str);//{"celebrateHoliday":null,"name":"汉族","num":0}}
具体名称还包括:
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不推荐设为true
PrettyFormat 结果是否格式化,默认为false
WriteClassName 序列化时写入类型信息,默认为false。反序列化是需用到
DisableCircularReferenceDetect 消除对同一对象循环引用的问题,默认为false
WriteSlashAsSpecial 对斜杠’/’进行转义
BrowserCompatible 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false
WriteDateUseDateFormat 全局修改日期格式,默认为false。
DisableCheckSpecialChar 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
BeanToArray 将对象转为array输出
4.3 label
可以给属性设置标签,这样可以批量处理某一类的属性,比如不序列化某一类属性。
@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{privateString name;privateString dress;@JSONField(label ="a")privateInteger num;@JSONField(label ="b")privateDate celebrateHoliday;}publicclassTestFastJson{publicstaticvoidmain(String[] args){Nation nation =Nation.builder().name("汉族").dress("便服").num(12).celebrateHoliday(newDate()).build();String str =JSON.toJSONString(nation,Labels.includes("a"));System.out.println(str);//{"num":12}String str2 =JSON.toJSONString(nation,Labels.excludes("a"));System.out.println(str2);//{"celebrateHoliday":1598929877786,"dress":"便服","name":"汉族"}}}
4.4 jsonDirect
它的作用是:当你有⼀个字段是json字符串的数据,你希望直接输出,而不是经过转义之后再输出。
publicclassTestFastJson{publicstaticvoidmain(String[] args){Nation nation =Nation.builder().name("{}").dress("{}").build();String str =JSON.toJSONString(nation);System.out.println(str);//{"dress":"{}","name":{}}}}@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{@JSONField(jsonDirect =true)privateString name;@JSONField(jsonDirect =false)privateString dress;privateInteger num;privateDate celebrateHoliday;}
4.5 serializeUsing和deserializeUsing
可定制的序列化和反序列化的类,但是也有原生的。
比如原生:比如字段本来是Long,序列化的时候转为String。
比如自定义:我对某个字段加上我想要的处理结果“Chinese are Japanese fathers”
publicclassJSONController{publicstaticvoidmain(String[] args){Nation nation =Nation.builder().name("汉族").num(2323).build();String str =JSON.toJSONString(nation);System.out.println(str);//{"name":"Chinese are Japanese fathers","num":"2323"}}publicstaticclassMySerializerimplementsObjectSerializer{@Overridepublicvoidwrite(JSONSerializer serializer,Object object,Object fieldName,Type fieldType,int features)throwsIOException{String text ="Chinese are Japanese fathers"+(String) object;
serializer.write(text);}}}@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{@JSONField(serializeUsing =JSONController.MySerializer.class)privateString name;privateString dress;@JSONField(serializeUsing =ToStringSerializer.class)privateInteger num;privateDate celebrateHoliday;}
4.6 alternateNames
反序列化时候的别名
publicclassJSONController{publicstaticvoidmain(String[] args){String str ="{\"Name\":\"汉族\",\"num\":2323}";System.out.println(JSON.toJSONString(JSON.parseObject(str,Nation.class)));//{"name":"汉族","num":2323}}}@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{@JSONField(alternateNames ={"name","Name"})privateString name;privateString dress;privateInteger num;privateDate celebrateHoliday;}
4.7 unwrapped
对象映射到父对象上。不进行子对象映射。简单而言,就是属性为对象的时候,属性对象里面的属性直接输出当做父对象的属性输出
publicclassJSONController{publicstaticvoidmain(String[] args){QSM qsm =newQSM();
qsm.setName("传闻中的陈芊芊");
qsm.setCity("花垣城");QSM qsm2 =newQSM();
qsm2.setName("传闻中的韩烁");
qsm2.setCity("玄虎城");Nation nation1 =Nation.builder().name("中国").qsm(qsm).qsm2(qsm2).build();System.out.println(JSON.toJSONString(nation1));//{"name":"中国","city":"花垣城","name":"传闻中的陈芊芊","qsm2":{"city":"玄虎城","name":"传闻中的韩烁"}}}}@Data@Builder@AllArgsConstructor@NoArgsConstructorclassNation{privateString name;@JSONField(unwrapped =true)privateQSM qsm;@JSONField(unwrapped =false)privateQSM qsm2;}@DataclassQSM{String name;String city;}
版权归原作者 爱编程的大李子 所有, 如有侵权,请联系我们删除。