FastJson使用技巧
创始人
2024-03-15 10:20:37
0

一、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 依赖:

com.alibabafastjsonx.x.x

其中 x.x.x 是版本号,根据需要使用特定版本,建议使用最新版本。

四、常见使用

4.1 @JSONField

使用fastjson进行需要对字段进行一些特殊处理,比如时间格式,前后端名字不一致,字段为null是否依然序列化等问题。那么fastjson的@JSONField就能很好的解决这些问题。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {int ordinal() default 0; //是根据fieldName的字母序进行序列的,你可以通过ordinal指定字段的顺序String name() default ""; //序列化和反序列化时候的别名String format() default ""; //用于字符串格式的日期转换boolean serialize() default true; // 是否参与序列化boolean deserialize() default true; //是否参与反序列化SerializerFeature[] serialzeFeatures() default {}; //序列化选项 SerializerFeature.WriteNullNumberAsZero 如空Number填充0Feature[] parseFeatures() default {}; //反序列化选项String label() default ""; //标签,boolean jsonDirect() default false; //当你有⼀个字段是json字符串的数据,你希望直接输出,⽽不是经过转义之后再输出。Class serializeUsing() default Void.class; // 属性的序列化类,可定制。可有现存的,比如本来是Long,序列化的时候转为String:serializeUsing= ToStringSerializer.classClass deserializeUsing() default Void.class; // 属性的反序列化类,可定制。String[] alternateNames() default {}; //参与反序列化时候的别名boolean unwrapped() default false; // 对象映射到父对象上。不进行子对象映射。简单而言,就是属性为对象的时候,属性对象里面的属性直接输出当做父对象的属性输出String defaultValue() default ""; //设置默认值
}

现在开始先介绍几个基本属性:ordinal 、name 、serialize、 deserialize、 format、defaultValue

/*** @author xuyang.li* @date 2022/12/3 11:56* @description*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person {@JSONField(ordinal = 1)private String name;@JSONField(name = "nation",defaultValue = "China",serialize = false)private String country;@JSONField(ordinal = 2,name = "old",deserialize = false)private Integer age;@JSONField(name = "num",defaultValue = "0")private Integer number;@JSONField(ordinal = 3,format = "yyyy-MM-dd")private Date birthday;
}public void testJsonField() {Person person = Person.builder().name("张三").age(18).birthday(new Date()).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
@NoArgsConstructor
class Nation {private String name;private String dress;@JSONField(serialzeFeatures = SerializerFeature.WriteNullNumberAsZero)private Integer num;@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue)private Date celebrateHoliday;
}public static void main(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
@NoArgsConstructor
class Nation {private String name;private String dress;@JSONField(label = "a")private Integer num;@JSONField(label = "b")private Date celebrateHoliday;
}public class TestFastJson {public static void main(String[] args) {Nation nation = Nation.builder().name("汉族").dress("便服").num(12).celebrateHoliday(new Date()).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字符串的数据,你希望直接输出,而不是经过转义之后再输出。

public class TestFastJson {public static void main(String[] args) {Nation nation = Nation.builder().name("{}").dress("{}").build();String str = JSON.toJSONString(nation);System.out.println(str); //{"dress":"{}","name":{}}}
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Nation {@JSONField(jsonDirect = true)private String name;@JSONField(jsonDirect = false)private String dress;private Integer num;private Date celebrateHoliday;
}

4.5 serializeUsing和deserializeUsing

可定制的序列化和反序列化的类,但是也有原生的。
比如原生:比如字段本来是Long,序列化的时候转为String。
比如自定义:我对某个字段加上我想要的处理结果“Chinese are Japanese fathers”

public class JSONController {public static void main(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"}}public static class MySerializer implements ObjectSerializer {@Overridepublic void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {String text = "Chinese are Japanese fathers" + (String) object;serializer.write(text);}}
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Nation {@JSONField(serializeUsing = JSONController.MySerializer.class)private String name;private String dress;@JSONField(serializeUsing = ToStringSerializer.class)private Integer num;private Date celebrateHoliday;
}

4.6 alternateNames

反序列化时候的别名

public class JSONController {public static void main(String[] args) {String str ="{\"Name\":\"汉族\",\"num\":2323}";System.out.println(JSON.toJSONString(JSON.parseObject(str, Nation.class)));//{"name":"汉族","num":2323}}}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Nation {@JSONField(alternateNames = {"name", "Name"})private String name;private String dress;private Integer num;private Date celebrateHoliday;
}

4.7 unwrapped

对象映射到父对象上。不进行子对象映射。简单而言,就是属性为对象的时候,属性对象里面的属性直接输出当做父对象的属性输出

public class JSONController {public static void main(String[] args) {QSM qsm = new QSM();qsm.setName("传闻中的陈芊芊");qsm.setCity("花垣城");QSM qsm2 = new QSM();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
@NoArgsConstructor
class Nation {private String name;@JSONField(unwrapped = true)private QSM qsm;@JSONField(unwrapped = false)private QSM qsm2;
}@Data
class QSM {String name;String city;
}

相关内容

热门资讯

烦恼即菩提出自哪里 烦恼即菩提出自哪里《六祖法宝坛经》中有
动漫《火影忍者》里,有哪些美女... 动漫《火影忍者》里,有哪些美女妈妈很“暴力”?奈良吉乃、奈良手鞠、旋涡玖辛奈、宇智波樱、大筒木辉夜等...
东临碣石,以观沧海,这个碣石,... 东临碣石,以观沧海,这个碣石,现于何地?如题。我去哪儿旅行能看到?山名,在现在河北昌黎.河北秦皇岛市...
人的正常生活应该是怎样的? 人的正常生活应该是怎样的?吃...喝...住...行...拉..撒~! 就这样~!穿衣,吃饭,睡觉...
赛尔号元素神殿在哪 怎么去 赛尔号元素神殿在哪 怎么去1.打开地图,进入“VIP殿堂\"。 .2.左下角进入”五彩云泽“。3.右...
当一个男人真正喜欢你的时候,一... 当一个男人真正喜欢你的时候,一定会出现哪些态度变化?男人会无时无刻的想念你,并且经常和你发信息和打电...
全球三大压缩机的排名次 全球三大压缩机的排名次灌水的走开,我要真实数据。全球三大压缩机的排名次 :1,丹麦:丹佛斯 2,巴西...
莲花梦迟女主都经历了什么 莲花梦迟女主都经历了什么该剧的女主经历了一系列悲剧。《莲花梦迟》的女主花怜是个孤儿,从小受到虐待和抛...
我来编童话作文 我来编童话作文   在平平淡淡的学习、工作、生活中,大家对作文都再熟悉不过了吧,借助作文可以宣泄心中...
前夫这么多年没联系,现在又来联... 前夫这么多年没联系,现在又来联系我,这是什么意思?爱情就是男女双方对彼此相互间相互依赖,相互包容,且...
爱情与友情的区别 爱情与友情的区别爱情是最强烈的情感,具有排他性,也最具备迷醉、疯狂性,友情和爱情比,更加平淡、温和一...
诉衷情宋陆游 诉衷情宋陆游诉衷情作者:陆游诉衷情·青衫初入九重城青衫初入九重城。结友尽豪英。蜡封夜半传檄,驰骑谕幽...
哪位知道蒙牛名称来历?可以告知... 哪位知道蒙牛名称来历?可以告知一下吗?说起蒙牛,几乎每个人都知道,但是说起牛根生,很多人不知道。牛根...
被很多人推崇的“轻断食减肥”,... 被很多人推崇的“轻断食减肥”,究竟是什么方法?这是因为很多人在决定减肥的时候都不会吃主食,而且有时候...
一生都衣禄无忧,初年财禄常在,... 一生都衣禄无忧,初年财禄常在,晚景有乘骨肉,头见女吉,迟生则好。 这些事什么意思是需要详细说明一生都...
简述三只乌鸦k线组合的市场含义 简述三只乌鸦k线组合的市场含义三只乌鸦等同于三兵形态的黑三兵,红三兵呈红柱状蜡烛形态一个比一个挂的高...
弈秋诲二人弈的原文 弈秋诲二人弈的原文弈秋,通国之善弈者也。使弈秋诲二人弈,其一人专心致志,惟弈秋之为听;一人虽听之,一...
一本小说主角是现代的 能召唤骷... 一本小说主角是现代的 能召唤骷髅来作战 骷髅可以自行杀鬼 主角能看到鬼魂 召唤骷髅来杀鬼楼主有答案了...
请君入瓮成语的意思 请君入瓮成语的意思已经准备好圈套,然后再请人进去
掌门休夫日常经验丹大怎么弄 掌门休夫日常经验丹大怎么弄配方:鹿茸+天山雪莲+千年人参。掌门休夫日常带你体验穿越到古代生活的剧情,...