乐趣区

关于java:吃透FastJSON认准此文

大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚!
死鬼~ 看完记得给我来个三连哦!

本文次要介绍 FastJSON 的应用

如有须要,能够参考

如有帮忙,不忘 点赞

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

JSON 介绍

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格局。它使得人们很容易的进行浏览和编写。同时也不便了机器进行解析和生成。它采纳一种 “ 键 : 值 ” 对的文本格式来存储和示意数据,在零碎替换数据过程中经常被应用,是一种现实的数据交换语言。

“XML 的时代曾经过来,当初是 JSON 的时代 ”。置信当初这个观点很多人曾经默默认同,那么咱们是否有认真思考过为什么当初 JSON 可能顶替 XML 的位置。咱们来简略看下两种的示意形式:

<?xml version="1.0" encoding="gb2312"?>
<class>
    <stu id="001">
        <name> 杨过 </name> 
        <sex> 男 </sex>
        <age>20</age>
    </stu>  
    <stu id="002">
        <name> 小龙女 </name>    
        <sex> 女 </sex>
        <age>21</age>
    </stu>
</class>
[
    {
        "id": "001",
        "name": "杨过",
        "sex": "男",
        "age": "20"
    },
    {
        "id": "002",
        "name": "小龙女",
        "sex": "女",
        "age": "21"
    }
]

两种形式都是用来形容简略的班级信息,信息不多,然而显著能够看出 JSONXML 更加简洁。具体区别可为以下几点:

  • 可读性: JSON 和 XML 的可读性堪称并驾齐驱,一边是繁难的语法,一边是标准的标签模式,很难分出输赢
  • 可扩展性: XML 天生有很好的扩展性,JSON 当然也有,因而 XML 能扩大的,JSON 也能够扩大
  • 编码难度: XML 有丰盛的编码工具,比方 DOM4J,JDom 等,JSON 也提供许多工具。然而在没有工具的状况下,因为 XML 有很多构造上的字符,编程难度绝对较高。
  • 解码难度: XML 的解析须要思考到子节点父节点,难度较大,而 JSON 的解析难度简直为 0,看上去就能了解数据结构

JSON 认知

JSON 具备以下模式
  • JSON 对象

{
    "id": "002",
    "name": "小龙女",
    "sex": "女",
    "age": "21"
}

这就是一个简略的 JSON 对象,咱们察看能够得出 JSON 的一些语法:

  1. 数据在花括号中 []
  2. 数据以 键 : 值 对的模式呈现(其中键多以字符串的模式呈现,值可为字符串,数值,以及 JSON 对象)
  3. 每两个 键 : 值 对以逗号分隔 ,,最初一个键值对需省略 ,

咱们依照下面的 3 点特色,便可很简略的构建出一个 JSON 对象

  • JSON 数组

["value1","value2","value3"]

[
    {
        "id": "001",
        "name": "杨过",
        "sex": "男",
        "age": "20"
    },
    {
        "id": "002",
        "name": "小龙女",
        "sex": "女",
        "age": "21"
    }
]

数组的示意形式也很简略:

  1. 头尾由 [] 包裹
  2. 数据主键以 , 隔开
  • JSON 字符串

'{"id":"001","name":" 杨过 ","sex":" 男 ","age":"20"}'

JSON 字符串与 Java 的字符串十分类似。

  1. 它必须以 "" 或者 '' 包裹数据,反对字符串的各种操作
  2. 外面的数据格式能够为 json 对象 ,也能够是 json 数组 亦或者是两个根本模式的组合变形

以上便是 JSON 的根本模式,JSON 能够应用于各种语言,每个语言皆有本人各自的 JSON 实现形式。上面咱们次要来相熟一下 Java 语言中的 FastJSON 的应用。

FastJSON

FastJSON 是由阿里巴巴工程师基于 JAVA 开发的一款 JSON 解析器和生成器,可用于将 Java 对象转换为其 JSON 示意模式,它还能够用于将 JSON 字符串转换为等效的 Java 对象。FastJSON 能够解决任意 Java 对象,包含没有源代码的事后存在的对象

FastJSON 应用非常不便,咱们只须要在 Maven 工程的 pom 文件中引入以下依赖即可:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.73</version>
</dependency>

FastJSON API 的入口类是 com.alibaba.fastjson.JSON,罕用的序列化操作都能够在 JSON 类上的静态方法间接实现。

API

咱们曾经在我的项目中引入 FastJSON 的依赖,和曾经存在了一个用户类:

@Data
public class User {
    private int id;

    private String name;

    private String sex;
    
    private int age;
}
toJSONString(Object o)

这个办法平时最常见了,将 JavaBean 序列化成 JSON 文本

咱们通过传入一个对象,便能够将对象转成 JSON 字符串,这里咱们传入的不仅仅是 JavaBean 还能够是一个 Map 对象

传入一个 Map 对象 咱们同样能够获取到一个 JSON 字符串。List 对象 也很实用:

后果是一个规范的 JSONArray 的字符串

如果说 toJSONString(Object o) 的输入后果只有枯燥的一行让你看起来有点吃力,那么咱们能够应用 toJSONString(Object o, boolean prettyFormat) 来让输入后果看起来难受点:

通过 JSON 自带的格式化,让输入后果看起来更加清晰,真是贴心~

有小伙伴预计想着这两种我平时都用腻歪了,哪里有的着在你这看,小菜一想,言之有理。那就介绍一下 toJSONString 的扩大用法。

JSON.toJSONString(Object object, SerializerFeature... features)

咱们能够看到这个办法外面有个参数 SerializerFeature...,可能感到有点生疏,的确,我也很生疏,咱们先来看下什么是 SerializerFeature,通过源码咱们能够发现 SerializerFeature 原来是个枚举类:

看到这张图咱们不要晕,外面尽管有很多实例,然而大部分都被 @deprecated 正文了,阐明这些曾经废除了。那有哪些是咱们平时常常用到的呢:

对象 形容
SerializerFeature.UseSingleQuotes 应用单引号而不是双引号,默认为false
SerializerFeature.PrettyFormat 后果是否格式化,默认为false
SerializerFeature.WriteDateUseDateFormat 如果工夫是 data、工夫戳类型,依照这种格局初始化工夫 “yyyy-MM-dd HH:mm”
SerializerFeature.WriteMapNullValue 是否输入值为 null 的字段,默认为false
SerializerFeature.WriteClassName 序列化时写入类型信息,默认为false

应用案例:

  • SerializerFeature.UseSingleQuotes

应用单引号而不是双引号, 默认为false

  • SerializerFeature.PrettyFormat

后果是否格式化, 默认为false

  • SerializerFeature.WriteDateUseDateFormat

如果工夫是 data、工夫戳类型,依照这种格局初始化工夫 “yyyy-MM-dd HH:mm”

通过这种形式咱们将日期输入成了固定的格局:yyyy-MM-dd HH:mm,有时候咱们不想失去这种格局那该怎么办,方法总会有的:

这个形式反对自定义工夫格局,然而用到办法是 toJSONStringWithDateFormat(),这里须要留神下,不要到时候用错了办法,还说小菜 渣男 ~

  • SerializerFeature.WriteMapNullValue

是否输入值为 null 的字段,默认为false

这个用什么用途了,咱们应该很分明开发标准中激励用 JavaBean 传递参数,尽量减少通过 Map 传递参数,因为 Map 相当于一个黑盒,对于使用者来说基本不晓得外面存在哪些字段,而对于创建者来说预计也会遗记外面存在哪些字段,为了解决这个痛,JSON 也推出了解决办法:

通过一般形式的 toJSONString() 办法,空值好像被 吃掉 了,这很可能会成为一个开发劫难!

  • SerializerFeature.WriteClassName

序列化时写入类型信息,默认为false。这个办法能够在反序列化的时候用到,用法如下:

通过这样咱们能够看到咱们序列化的对象是什么类型的。

下面这些便是 toJSONString 的扩大用法,小伙伴们有没有满满的播种~

vx 搜:小菜良记

更多干货值得关注,每篇都是初恋的滋味,钉~

  • parseObject(String text)

下面说到的是 序列化 ,那么对应的便是 反序列化

反序列化就是把 JSON 格局的字符串转化为 Java Bean 对象。

用法非常简略,能够将一个规范的 JSON 字符串 转为一个 JSONObject 对象,因为 JSONObject 类 实现了 Map 接口,因而咱们能够通过 get() 来获取到值。

咱们曾经晓得了 Map 的致命有余,所以咱们更心愿能失去一个 JavaBean 对象。

当然也是能够的!咱们通过传入咱们想要转换的对象类型,就能够失去咱们想要的 JavaBean

除了 根本反序列化 之外,还有一种 泛型反序列化 可供使用

通过 泛型,咱们就能够不必传入一个 Class 对象,而间接获取到咱们的 JavaBean

FastJSON 序列化还有一个用途那便是进行 深克隆 。有看过我后面文章的小伙伴们置信当初对软件设计模式都有肯定的理解了,其中 原型模式 波及到的 深克隆 浅克隆

浅克隆的实现形式非常简略,咱们只须要实现 Cloneable 接口,而后重写 clone() 办法 :

后果中咱们看到的 坏蛋卡 都是属于 小王 的,这就是 浅克隆 的弊病的了。咱们想要实现 深克隆 有许多种形式:

  • 手动为援用属性赋值
  • 借助 FastJSON
  • 应用 java 流 的序列化对象

办法有许多,咱们重点看下 FastJSON 的实现形式:

通过 FastJSON 的反序列化,咱们失去的两个对象实际上是不同的,这也很不便的实现了 深克隆

更多设计模式的理解,各位请移位:

2021 还不多学几种创立型模式,创立个对象!

图文并茂走进《结构型模式》,原来这么简略!

敲黑板了!《行为型模式》来袭

parseArray(String text)

这是一个将 JSON 字符串 转为 JSONArray 的办法

同样咱们也能够通过应用 泛型序列化 来实现同样的性能:

这种形式有个坑就是:咱们应用 parseArray() 这个办法的时候第二个参数须要传入咱们要反序列化的对象类型,然而咱们这里须要传入的是数组,不晓得你有没有为数组里放了两个一样的 type 感到奇怪?没错,这就是这个办法的坑,咱们 List 外面有多少个对象,Type[] 这个数组外面的个数要与之匹配,不然会抛出以下谬误:

然而如果一个 List 中存在多个不同类型的对象时,咱们能够应用这个办法:

toJSONBytes(Object o)

JSON 对象转换成 Byte(字节) 数组

咱们平时在进行网络通讯的时候,须要将对象转为字节而后进行传输。咱们应用字符串的时候,不禁然的能够想到字符串中有个很便捷的 API 能够将字符串转为字节数组

String str = "小菜";
byte[] bytes = str.getBytes();

然而咱们如果要将一个 JavaBean 对象转为字节数组的时候,咱们得借助 ByteArrayOutputStream 流的帮忙:

这种形式也能够很好的将 JavaBean 对象转为字节数组,然而代码未免有点多了!而 FastJSON 中也提供了很不便的 API 以供应用:

而咱们要将字节数组转为对象,FastJSON 也同样反对:

parseObject() 这个办法中咱们又看到了一个奇怪的参数 Feature,咱们点击进入源码能够发现这其实也是一个枚举类:

看的同样云里雾里的,这么多对象实例,以下咱们对比拟罕用的做出了正文:

对象 形容
AllowUnQuotedFieldNames 决定 parser 是否将容许应用非双引号属性名
AllowSingleQuotes 决定 parser 是否容许单引号来包住属性名称和字符串值
InternFieldNames 决定 JSON 对象属性名称是否能够被 String#intern 规范化示意,如果容许,则 JSON 所有的属性名将会 intern();如果不设置,则不会规范化,默认下,该属性是凋谢的。
AllowISO8601DateFormat 设置为 true 则遇到字符串合乎 ISO8601 格局的日期时,会间接转换成日期类
AllowArbitraryCommas 容许多重逗号, 如果设为 true, 则遇到多个逗号会间接跳过
UseBigDecimal 设置为 true 则用 BigDecimal 类来装载数字,否则用的是 double
IgnoreNotMatch 疏忽不匹配
DisableCircularReferenceDetect 禁用循环援用检测
InitStringFieldAsEmpty 对于没有值得字符串属性设置为空串
SupportArrayToBean 反对数组 to 对象
OrderedField 属性放弃原来的程序
DisableSpecialKeyDetect 禁用特殊字符查看
UseObjectArray 应用对象数组
writeJSONString(OutputStream os, Object o)

这个办法是将对象写入输入流中的:

传入的参数还能够是一个 Writer 对象:

以上便是咱们平时罕用的 API,除此之外,在 FastJSON 中还有一个注解 @JSONField 咱们也要学会灵活运用

@JSONField
命名重塑

注: 若属性是 公有 的,必须要有 set() 办法,否则无奈反序列化!

@JSONField 用法简略,能够配置在 getter()setter() 或者 属性字段

测试后果:

这个办法的最大益处便是用来对接奇奇怪怪的文档,为什么说奇奇怪怪呢,有时候咱们须要调用第三方的接口,然而这个接口返回的值可能是不合乎命名标准的,那咱们这边就须要定义一个实体类去接管它(Map 尽管也行,然而也不标准)。

这个时候咱们定义的实体类的属性名就得依照返回的字段名来命名,这对强迫症程序猿来说是致命打击,这个时候 @JSONField 的用途就来了,咱们简略看个例子。有个车牌信息实体的返回字段是这样的:

{"PLATEID" : 01, "PLATE": '闽 A6666D', "IMAGEURL":'http://...'}

咱们能够看到返回的字段名全都不满足小驼峰规定,咱们定义的实体类可不能这样,借助 @JSONField 的写法如下:

测试下是否可能胜利接管后果:

能够看到咱们曾经胜利接管到后果了,而且实体类的命名也合乎咱们的标准,两全其美。

DataFormat

咱们也能够应用该注解来将咱们的日期格式化成咱们想要的样子

管制序列化

在序列化或反序列化的时候咱们能够指定字段不序列化,这个有点像 Java 流 中的 transient 润饰。FastJSON 中也能够实现类似的性能:

然而反序列化有个毛病就是,尽管值是空的,然而属性名还在~

ordinal

咱们能够应用 ordinal 来指定字段的程序

通过接管后果能够看到 属性字段 依照咱们规定的程序所排列,用途能够在于咱们返回字段给前端过多的时候,将有用的字段优先排列到后面,能够更好的取值,而不必一层一层的查找须要的字段。

定制序列化

万物皆可定制,序列化也不例外~ 咱们能够应用 serializeUsing 制订属性的序列化类

通过这种形式咱们针对 age 这个属性进行了解决,给指定字段加上了单位.

这篇带来的就是 FastJSON 的应用,心愿能给各位小伙伴带来版主,路漫漫,小菜与你一起求索~

明天的你多致力一点,今天的你就能少说一句求人的话!

我是小菜,一个和你一起学习的男人。 ????

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

每篇都是初恋的滋味哦~

退出移动版