标签:年龄 单词 遵从 式表 treemap 除了 联系 print ocs
本文原创作者
bigsai
(同公众号),本文以浅显易懂的方式给大家讲解自己所认知的json,如果有错误或者不准确地方还请大家给出指正,另外本文以关卡课程的方式在博学谷也是免费开放的,大家也可通过关卡方式学习。
在开始之前,问个问题,什么是json?
json它不是一个原有单词,其实是4个单词JavaScript Object Notation(JavaScript对象表示)的简写,是一种轻量级的文本数据交换格式,并且json独立于语言(使用JavaScript语法描述对象),很多编程语言都支持json。 json 已成为当前服务器与 web 应用之间数据传输的公认标准。
问个问题,json是如何诞生的呢?
这个问题首先由于互联网应用之间需要传输数据,且很多跨平台的程序需要交互,只能采取纯文本方式的交互,而xml当初就是一个选择,但是xml规范越来越多也越来越复杂,解析效率也比较低,很多攻城狮看到xml头都大了,可能搞了很久也搞不明白。
然后独钟于JavaScript的JavaScript大宗师(JavaScript之父评价)Douglas Crockford根据JavaScript的规范发明推广了json,json格式简单易用,且同样可跨平台传出,得到广泛的认可和传播。就这样,json就越来越流行了,现在已经成为主流技术之一。
(选择题)章节练习:json是一种什么东西呢(B)?
谈起json,那xml肯定是少不了对比的东西啊,没有对比就是没有伤害,在和json履行相同职责的文本传输交换格式还有json的老大哥xml(可扩展标记语言),在json横空出世以前,咱们用的可都是xml进行文件数据传输。
首先咱们要从定义上来看看json和xml的区别:
JSON(JavaScript Object Notation)
一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。其语言习惯具备类c的习惯体系(c,c++,java等)。
XML(Extensiable Markup Language,可扩展标记语言)
用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
json的横空出世,是充分吸取借鉴了xml的优点,故json和xml有着一些相同的优点:
但json毕竟青出于蓝而青于蓝,肯定有着xml一些没有的特点和优势,例如:
尽管如此,xml仍有它独有应用领域:
当然,不是所有的json都是"特仑苏",适合场景需要的才是最好的。但在web领域的数据传输,它就是王者!
(选择题)小练习:下列哪一项是错误选项?(B)
json之所以很流行,是因为json有着广泛的应用领域。主要包括与ajax结合使用的统一平台的前端传输;跨平台的数据传输;非关系型数据库的文档存储等。这些领域通过使用json使得应用效率大大提高。
json本身就起源于JavaScript,JavaScript解析处理json有天然的优势,而在Ajax异步加载的数据中,整体页面已经加载过了,我们只需要在对应位置渲染真实的数据就行了,。而这部分的真实数据我们用json文本来存储,使用JavaScript异步向服务端请求,请求成功之后JavaScript对其渲染填充就可以了。下图就是对前后端交互传统方式和ajax异步交互的简要描述:
如果对AJAX也不熟悉?流程也看不懂,也不能明白异步传输的真谛在哪里,那好咱们以下图这个例子来解释一下,对于一个非常庞大的网页部分,可以有各个模块组成,其中评论模块是我们非常小的模块,但是评论可能涉及很多条可能涉及分页,如果我们每次为了看下一页的评论,点击下一页就向服务端请求整个页面资源进行刷新,那样就太浪费服务端资源和带宽了(就评论的文本变了,就要把其他模块全部渲染一遍?)
所以我们采取所谓AJAX异步更新这个东西,也就是通过JavaScript请求下一页的评论相关数据(用json
作为数据交互文本),JavaScript得到这串json字符串中就有页面需要的评论信息,然后我们强大到无所不能的JavaScript将这部分重现渲染到评论模块的对应位置。
这个流程下来,我们不仅节约了带宽,提高了响应速度,还提高了服务器相对负载能力(每次请求需要的资源更少),提高了用户的使用体验,还提高了------(此处省略万字)
前面提到的是前后端的交互,前提是后端同是一门编程语言、平台,向前端提供服务。但随着互联网的发展,很多时候会遇到服务拆分、跨平台等服务的需要。而跨语言跨平台的最大障碍就是服务的交流问题。你总不至于用你电脑上的c++代码直接调用我电脑上某个java函数吧?为了解决这种问题,这时候通过restful风格的接口和json作为文本传输的格式就能良好的解决服务通信问题。
例如某个公司业务太大,将服务分配给A团队和B团队。很多时候A可能需要进行调用B服务。如果A团队全部是java,B团队全部是php,互相喊着天下第一不肯相让。这该怎么办?那么通过json进行通信是一种非常好的方式。流程如图简要所示:
随着互联网web2.0网站的兴起,传统关系数据库在处理超大规模网站和高并发方面显得有点力不从心。而非关系型的数据库由于它本身的特点得到非常迅速的发展,非关系数据库在大规模数据下也有非常良好的读写性能,且数据之间无关系,无形之间就在架构层面带来了可拓展的能力。
而有很多基于文档存储的非关系数据库采取json作为其存储格式,其中比较著名的有:MongoDB、CouchDB、RavenDB等。存储的内容是文档型的,这样也有机会对某些字段建立索引,实现关系数据库的某些功能。
有些同学可能会问:既然json可以,那xml可以实现相似功能嘛?
答案是不可以,因为像xml类型的字段,不管是查询还是更改效率都很一般,主要原因是是DB层对xml字段很难建高效索引,应用层又要做从字符流到dom的解析转换。NoSQL以json方式存储,提供了原生态的支持,在效率方面远远高于传统关系型数据库。
此外,Elasticsearch等搜索引擎还用json和java api 提供其所有特性和功能。json在开源中间件的应用也越来越多!
(多选题)小练习:json常用于以下那些领域?(ABC)
json语法是JavaScript语法的子集,而json一般也是用来传输对象
和数组
。也就是json语法是JavaScript语法的一部分(满足特定语法的JavaScript语法)。
json 数据的书写格式为:"名称":"值"
。
对应JavaScript的概念就是:名称="值"
但json的格式和JavaScript对象格式还是有所区别:
json有两种表示结构—对象和数组,通过着两种表示结构可以表示更复杂的结构。对比java的话json数组和json对象就好比java的列表/数组(Object类型)和对象(Map)一样的关系。并且很多情况其对象值可能相互嵌套多层,对对象中存在对象,对象中存在数组,数组中存在对象…下面这张图能够一定程度反应json对象和数组的关系:
json对象很容易理解,它代表一个实体,这个实体有一些其他的属性,这些属性可能是数字、字符串(要双引号)、逻辑值、对象(加大括号)、数组(中括号)、null。如果从java语言来看他就是对应一个实体类或者一个Map,其中有一些用键值的方式描述名称和值。
var a = {"name":"bigsai" , "sex":"man","school":{"name":"博学谷","localtion":"Bei Jing"}};
取值:可以通过(.)或者([])进行取值,例如a.name(a.sex)
和a["name"](a["sex"])
,代码解释如下:
对象套对象:可以通过(.)或者([])进行取值。代码解释如下:
遍历:可以用 for - in 进行对象遍历。代码解释如下:
修改:可以使用(.)或者([])进行修改对象的值。示例代码如下:
删除:可以通过delete关键词删除json对象属性值。示例代码如下:
完整代码截图为:
附上代码:
var a = {"name":"bigsai" , "sex":"man","school":{"name":"博学谷","localtion":"Bei Jing"}};
a.name+" "+a["name"]
a.school
a["school"].name
for (key in a){//遍历对象
console.log(key+" "+a[key]);}
a.name="saisai"
a["sex"]="woman"
a
delete a["school"]
a
学习完json对象,那么json数组的学习就容易的多了。json数组与json对象有一些区别,json数组用中括号表示([]
),各个值用逗号(,
)分隔,并且数组值需要是json合法数据类型(字符串, 数字, 对象, 数组, 布尔值或 null).
var names=["bigsai","bigpian","bigbig"];//json数组
var students=[{"name":"bigsai","high":180},{"name":"bigpian","high":165},{"name":"Yao Ming","high":226}];//对象套数组
取值:可以通过中括号([]
)进行取值,例如names[0]
或names["0"]
,示例代码如下:
在这里插入图片描述
数组套对象:取值到对象后遵从对象的语法。示例代码如下:
遍历:可以用 for - in 或者for 对json数组进行遍历。示例代码如下:
修改:可以使用([]
)索引号进行修改数组。示例代码如下:
删除:可以通过delete关键词删除json数组中的项目。示例代码如下:
完整json数组示例代码如下:
附上源码:
var names=["bigsai","bigpian","bigbig"];//json数组
var students=[{"name":"bigsai","high":180},{"name":"bigpian","high":165},{"name":"Yao Ming","high":226}];//对象套数组
names["0"]+" "+names[0]//json数组取值
students[2]["name"]+" 身高:"+students[2].high//json数组套对象(对象套数组同理)
for (i in names){ console.log(names[i]); }//for in 遍历
for (i=0;i<names.length;i++){console.log(names[i]);}
names[0]="bigsai666";
delete names[0];
names
在JavaScript中谈到json,很多人会对JavaScript对象、json对象、json字符串混淆和概念不清晰,我们可以举个例子来一起看一下:
var a1={ name:"bigsai" , sex:"man" };//JavaScript对象
var a2={‘name‘:‘bigsai‘ , ‘sex‘:‘man‘};//JavaScript对象
var a3={"name":"bigsai" , "sex":"man"};//满足json格式的JavaScript对象
var a4=‘{"name":"bigsai" , "sex":"man"}‘;//json字符串
总的来说:
JavaScript对象:除了字符串、数字、true、false、null和undefined之外,JavaScript中的值都是对象。
json对象:这个说法其实不太准确,没有单独的json对象,我们常说的json对象它实质是满足json格式要求的JavaScript对象。如上a3对象。
json字符串,满足json语法格式的字符串(json是一种数据格式),有时也称json串。
在这里多说几句,你可能会对json对象还是有点不够清晰,你可能在其他地方也会遇到json对象。首先,json是一种数据格式,而json有对象和数组两种具体表现格式。
总的来说,我们通常说的json对象、json数组它实质是一种数据格式。但同在在不同语言中满足这种格式要求的对象、数组我们会称其为json对象、json数组。
(选择题)小练习:下列哪一项是满足json格式的JavaScript对象?(D)
本章小结:大家可以发现json的语法规则还是相对简单的,对于json语法格式,大家要谨记json的数据名称只能是带双引号(""
)的字符串,而json对象的值要谨记有哪几种满足的类型。对于json对象和json数组来说,是json的两种表示结构,而json的灵活性也允许两种类型的相互嵌套,可以表示更为复杂的结构。
(单选题)既然大家和我一起学了json对象、数组以及一些基本语法,下面考考大家,json对象的值不可以是下面哪种类型呢?(D)
前面我们学习了json的一些概念和基础语法,也知道了json起身于JavaScript,在很多语言如python中得到较好的支持,但也有很多语言从语言本身来说是不支持json的(就比如咱们强大的java)。这虽然是一大障碍但并不阻止我们在java这门语言中使用json。我们可以通过添加一些工具包使得java支持json处理。
这些工具包能够将json字符串转换成java对象,从而在Java中使用。反过来也可以将java对象转换成json字符串,从而更广泛地用在其他地方。将Java对象到Json字符串的过程我们称为Serialization序列化,将Json字符串转换成Java对象的过程我们称为Deserialization反序列化。
如果理解起来容易混淆,那么可以借助下面这张图进行结合记忆:咱们从java角度来看,java对象需要从一个整体对象拆分成一个个碎片按序列往json字符串中写入,这就是一个序列化过程。而json字符串的一个个碎片反过来重新组装成一个完整的java对象这个过程就是反序列化。
对于json本身来说是不复杂的,但是在java中如果程序员直接操作json字符串那是一件非常麻烦和复杂的事情,不少优秀的程序员/团队/公司努力研究,将他们经验和智慧开源出来供大家使用,在其中,Gson/fastjson/Jackson要更流行一些。咱们一个个了解一下。
在学习之前,你知道什么是Gson吗?
Gson是谷歌开源的一个Java库,可用于将Java对象转换为(序列化)其JSON表示形式。它还可以用于将JSON字符串转换为(反序列化)等效的Java对象。Gson可以处理任意Java对象,包括没有源代码的现有对象。下图为Gson在github主页一些信息。
在这里
每种json工具包都有它自己的优点和长处,对于Gson来说,有以下几点特点:
下面和大家一起动手进行Gson实战,Gson的功能比较强大,在这里呢和大家一起实现一些基础和常用的使用。
首先创建一个java项目(Maven),要引入Gson的Maven依赖或jar包,其Maven依赖为:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
有了Gson的依赖之后,那么实现Java对象与Json的转化也就很简单啦,大体就是分为两步啦:
javaBean与json字符串互相转换:
首先创建一个student对象
public class student {
private String name;
private int age;
private String sex;
public student(String name, int age, String sex) {//构造方法
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {//重写toString方法
return "student{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", sex=‘" + sex + ‘\‘‘ +
‘}‘;
}
public String getName() {//获取name字符串
return name;
}
public void setName(String name) {//设置对象name
this.name = name;
}
public int getAge() {//获取年龄int
return age;
}
public void setAge(int age) {//设置年龄值
this.age = age;
}
public String getSex() {//获取性别
return sex;
}
public void setSex(String sex) {//设置性别
this.sex = sex;
}
}
其次,在测试中进行JavaBean(student)与json字符串的转换。主要通过toJson()和fromJson()进行序列化和反序列化操作。toJson,直译过来就是“到达json”,所以是将java对象转成json字符串,也就是序列化。fromJson,直译过来就是“来自json”,所以是将json字符串转化为java对象,也就是反序列化。
//Gson gson= new GsonBuilder().create();//可以自定义一些配置
Gson gson=new Gson();//创建json对象
//java对象 to json
student stu=new student("Ben",22,"man");
String stustr=gson.toJson(stu,student.class);//json转为string
System.out.println("student对象为"+stu.toString());
System.out.println("转化为json字符串:"+stustr);
//json to java对象
///满足条件的json字符串{"name":"tony","age":32,"sex":"woman"}
String jsonstr="{\"name\":\"tony\"," +
"\"age\":32," +
"\"sex\":\"woman\"}";
student jsonstrobject=gson.fromJson(jsonstr,student.class);//转换为student对象
System.out.println("json字符串为"+jsonstr);
System.out.println("转化为student对象为:"+jsonstrobject.toString());
执行的结果为:
java集合与json字符串互相转化:
在实际开发中,我们很可能遇到的并不是javaBean与json字符串的直接转化,而是集合之类的转化工作,java集合种类繁多。在此,我们实现Map、List、String数组的序列化和反序列化操作。
在进行序列化操作时,我们首先创建Map<String,String>
,List<Object>
,String[]
对象然后填充一定数据以便进行序列化和反序列化操作。
Gson gson=new Gson();//创建json对象
//Map
Map<String,String>map=new HashMap<>();//Map
map.put("博学谷","666");map.put("小老弟","要加油");
//List
List<Object>list=new ArrayList<>();//List类型
list.add("hello");list.add("world");list.add(map);
//String[]
String []str={"Hello","World"};//String
String mapTojsonStr=gson.toJson(map);//{"小老弟":"要加油","博学谷":"666"}
String listTojsonStr=gson.toJson(list);//["hello","world",{"小老弟":"要加油","博学谷":"666"}]
String strTojsonStr=gson.toJson(str);//["Hello","World"]
System.out.println("Map转为json:"+mapTojsonStr);
System.out.println("List转为json:"+listTojsonStr);
System.out.println("String[]转为json:"+strTojsonStr);
执行的结果为:
我们将这些字符串复制到新的代码域进行反序列化操作,在反序列化时候,我们会用到fromJson()这个函数时,有两种我们常用的构造方式fromJson(String json, Class<T> classOfT)
和fromJson(String json, Type typeOfT)
,如果遇到泛型等类型时候需要借助 TypeToken来获取对象类型。
Gson gson=new Gson();//创建json对象
String mapTojsonStr="{\"小老弟\":\"要加油\",\"博学谷\":\"666\"}";//{"小老弟":"要加油","博学谷":"666"}
String listTojsonStr="[\"hello\",\"world\",{\"小老弟\":\"要加油\",\"博学谷\":\"666\"}]";//["hello","world",{"小老弟":"要加油","博学谷":"666"}]
String strTojsonStr="[\"Hello\",\"World\"]";//["Hello","World"]
//方式一方便简洁(这里避免冲突注释掉)
//Map<String,String>map1=gson.fromJson(mapTojsonStr,Map.class);
//方式二可以获取泛型等数据类型
Map<String,String>map1=gson.fromJson(mapTojsonStr,new TypeToken<Map<String,String>>(){}.getType());
List<Object>list=gson.fromJson(listTojsonStr,List.class);
Map<String,String>map2=(Map<String,String>)list.get(2);
String str[]=gson.fromJson(strTojsonStr,String[].class);
System.out.println("json转Map:"+map1.toString());
System.out.println("json转List"+list.toString());
System.out.println("map1和map2是否相等:"+map2.equals(map2));//相等
System.out.println("String[]:"+ Arrays.toString(str));
输出结果为:
上面只是介绍了java对象与json字符串的转换,实际上Gson不仅入手容易,还有其他非常强大的功能,在使用Gson开发中除了java对象和json字符串的转换,我们经常也会对JsonObject直接进行操作(类似JavaScript中操作json串一样),这里你需要了解学习Gson封装的JsonEelement,JsonObject,JsonArray,JsonPrimitive,JsonNull等数据类型。
不同的数据类型有各自的使用场景,下面给大家介绍下各个数据类型之间的区别与联系:
对于这些数据类型,你可能会问:为啥json字符串已经可以和java对象互相转了,还需要这些数据类型呢?
答案是这些数据类型让java中多一种可以处理json格式数据的方式。一方面让java处理json格式数据更加灵活,另一方面在某些场景下这样直接操作JsonObject、JsonArray等能够简化工作流程。
其实这些数据类型就是相当于用java的数据结构构造一个json的数据结构和方法(java本身不直接支持json),让我们能够直接使用和操作json。
从上图可以看得出,上面这些数据结构也是根据java的一些数据结构作为存储,然后写一些操作函数,封装一些方法。当然,JsonObject也可以通过Gson的toJson()和fromJson()方法灵活转成字符串和java对象。
有很多时候我们后台处理接受到的是一个json字符串,可能其内部结构也很复杂,如果我们将其转成java对象可能要编写java对应的实体,但是如果直接操作json对象可能就省下一些操作和流程,如果只需增删改其中很小的一部分,那么这种选择也是一种不错的方案。当然具体的使用方法和方案还需要根据具体的业务来判断!
(多选)既然学习了Gson,那么就来考考大家到底有没有真的掌握Gson的关键函数,仔细思考哦,这题有点狠,一错俱错呦:(AD)
除了谷歌的Gson,咱们国内也有一款非常强大的java序列化工具包—fastjson。下图为fastjson在github的主页:
在
学习fastjson之前同样问:什么是fastjson?
除了是国内阿里开源的,fastjson还有优异的性能,fastjson的优点如下:
下面带大家实战fastjson,同样首先我们需要引入依赖,下载jar包引入或者maven的依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
fastjson与Gson虽然大体相似但有所区别,fastjson自己也有实现的JSONObject,JSONArray类,前面在Gson中介绍过此类的作用我们在进行转换时候就把JSONObject加入进行转换。在fastjson主要提供以下三个类:
(1)JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换。
(2)JSONObject:fastJson提供的json对象。
(3)JSONArray:fastJson提供json数组对象。
json字符串、JSONObject及JavaBean之间的相互转换
首先,我们同样定义一个student类(同Gson的student类)
public class student {
private String name;
private int age;
private String sex;
public student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//get set方法
}
在测试代码中,我们分别编写一些代码实现三者的相互转换,但JSONObject、JSONArrray、JSON以及fastjson仍然有很多方法功能在这里就无法进行很详细的展示了:
//对象转json字符串,JSONObject
student student1=new student("xiaoming",5,"man");
String jsonstr1= JSON.toJSONString(student1);//对象转json字符串
JSONObject jsonObject1=(JSONObject) JSON.toJSON(student1);//对象转JSONObject
System.out.println(jsonObject1.toString());
System.out.println(jsonstr1+"\n");
//json字符串转java对象,JSONObject
String jsonstr2="{\"age\":5,\"name\":\"xiaoming\",\"sex\":\"man\"}";
JSONObject jsonObject2=JSON.parseObject(jsonstr2);//json字符串转JSONObject对象
student student2 = JSON.parseObject(jsonstr2,student.class);//json字符串转java对象
System.out.println(jsonObject2.toString());
System.out.println(student2.toString()+"\n");
//JSONObject 转java对象,json字符串
JSONObject jsonObject3=jsonObject2;
jsonObject3.put("age",18);//修改年龄
student student3=jsonObject3.toJavaObject(student.class);//JSONObject转java对象
String jsonstr3=jsonObject3.toJSONString();//JSONObject转json字符串
String name=jsonObject3.getString("name");//JSONObject取值
int age=jsonObject3.getInteger("age");
String sex=jsonObject3.getString("sex");
System.out.println("姓名"+name+" 年龄"+age+" 性别"+sex);
System.out.println(student3.toString());
System.out.println(jsonstr3+"\n");
对应输出的结果与预期一致:
json字符串、JSONObject及Java集合相互转换
上面进行了基于javabean的一些转换和操作,下面我们进行对java集合的一些转化实战。看看fastjson又是以什么样的参数进行的。java的Map是常用集合之一,咱们先看看Map的相关转化:
//map的相关转化
Map<String,String>map1=new HashMap<>();
map1.put("name","xiaoming");map1.put("sex","woman");
String jsonstr=JSON.toJSONString(map1);//Map转json字符串
JSONObject jsonObject=(JSONObject) JSON.toJSON(map1);//Map转json对象
System.out.println(jsonstr);
System.out.println(jsonObject.toString());
//Map<String,String>map2=JSON.parseObject(jsonstr,Map.class);//方式一
Map<String,String>map2=JSON.parseObject(jsonstr,new TypeReference<Map<String, String>>(){});//方式二json字符串转Map
Map<String,String>map3=jsonObject.toJavaObject( new TypeReference<Map<String, String>>(){});//JSONObject
System.out.println(map2.toString());
System.out.println(map3.toString());
控制台的输出为:
此外,List同样也是java中使用较多的集合之一,咱们可以看下它的相关转化:
//List相关转化
List<Map<String,String>>list1=new ArrayList<>();//集合
Map<String,String>map1=new HashMap<>();
map1.put("name","map1");
Map<String,String>map2=new HashMap<>();
map1.put("name","map2");map2.put("sex","man");
list1.add(map1);list1.add(map2);
String jsonstr=JSON.toJSONString(list1);//list转json字符串
JSONArray jsonArray =(JSONArray) JSON.toJSON(list1);//list转jsonArray
JSONObject jsonObject=jsonArray.getJSONObject(0);
System.out.println(jsonstr);
System.out.println(jsonArray+" "+jsonArray.get(0));
//json 字符串转list
List<Map<String,String>>list2=JSON.parseObject(jsonstr,new TypeReference<ArrayList<Map<String,String>>>(){});
//List<student>list3=JSON.parseArray("",student.class);//普通list的转换方式
System.out.println(list2.get(0).equals(map1)+" "+list2.get(1).equals(map2));//如果相等则证明成功序列化
System.out.println(list2.toString());
得到输出结果为:
不难看的出,fastjson在入门还是非常简单的。并且和Gson有很多相似之处,在Api的设计方面,Gson需要一个Gson对象来进行相关操作,而fastjson的JSON、JSONObject、JSONArray定义了很多静态的方法可以直接使用。同时两者的反序列化的TypeToken(Gson)和TypeReference(fastjson)有异曲同工之妙。
这两者在开发过程中使用很多,各有优劣,并且这里只是里面很小的一部分内容,要想深入学习还需要了解官方全面API才行(Gson官方API,fastjson官方文档)。但是对于fastjson来说,有些地方可能存在一些漏洞和不稳定因素,但是阿里很快就进行修复。所以在实际使用中要考虑fastjson的安全性。
(习题)介绍完咱们国内开源的科技—fastjson,那么我来看看对fastjson掌握程度如何,考考大家:下面哪个不是fastjson的类(D)
最后咱们介绍的就是当前更为成熟一点的jackson。jackson 是一个能够将java对象序列化为json字符串,也能够将json字符串反序列化为java对象的框架。下图为jackson在github主页情况:
其实jackson的应用非常广泛,在这里我们简单了解以下jackson然后对比分析三个json工具包的异同,对于jackson来说,拥有以下几点优势:
下面带大家实战jackson,在Gson和fastjson使用时只需引用一个jar,而jackson却不是将所有全部集成到一个jar内,而是分成了多个不同的模块(不同模块具有不同功能),咱们首先引入jackson的依赖:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.0</version>
</dependency>
有了jackson依赖之后,我们就可以进行实战了,在jackson中有三种方式操作json:
javaBean与json字符串相互转换
对于javaBean,我们创建student类(注意使用jackson的类必须有空参构造器):
public class student {
private String name;
private int age;
private String sex;
public student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public student(){}//空参构造器
//get set方法 toString方法
}
在测试代码中,首先创建一个ObjectMapper对象,序列化和反序列化都需要它。然后根据writeValueAsString()这个函数就可以把java对象转成json字符串(序列化)。而json字符串通过readValue()就可以将json字符串转化为java对象(反序列化)。代码的展示如下:
//创建 ObjectMapper对象
ObjectMapper mapper=new ObjectMapper();
//序列化的实体类
student stubigsai=new student("bigsai",6,"man");
//writeValueAsString()方法进行序列化
String stubigsaistr=mapper.writeValueAsString(stubigsai);
System.out.println(stubigsaistr+"\n");
//反序列化的json字符串
String stuxiaohongstr="{\"name\":\"xiaohong\",\"age\":8,\"sex\":\"woman\"}";
//readValue()方法进行反序列化
student stuxiaohong= mapper.readValue(stuxiaohongstr,student.class);
System.out.println(stuxiaohong.toString());
对于上述代码执行结果为:
java集合与json字符串相互转换
除了javaBean和json字符串转换外,java集合和json字符串的转换也很简单,我们这里就只演示java的Map与json字符串相互转化了,其流程与上述的javaBean和json互转有点类似。需要注意的是从json转换为Map对象(或其他泛型对象)的时候,由于Java的类型擦除,有些无法直接正确转换的类型需要我们手动用new TypeReference给出,实例代码如下:
//创建 ObjectMapper实体类
ObjectMapper mapper=new ObjectMapper();
//需要序列化的Map和List
Map<String,Object>map1=new HashMap<>();
map1.put("博学谷","666");map1.put("bigsai",666);//注意两个666类型不同
map1.put("string",new String[]{"bigsai", "博学谷"});
//序列化结果
String map1str=mapper.writeValueAsString(map1);
System.out.println(map1str+"\n");
//方式一反序列化结果
Map<String,Object>m1=mapper.readValue(map1str,Map.class);
//方式二TypeReference指定反序列化类型(适合泛型和复杂类型)
Map<String,Object>m2=mapper.readValue(map1str, new TypeReference<Map<String, Object>>() {});
System.out.println(m1.toString());
System.out.println(m2.toString());
执行结果为:
在这里插入图片描述
看完实例,你是不是发现:哇,原来三者有很相似的之处啊,是的,一个优秀的开源框架不光光要考虑其功能、性能,其易用性、对用户友好程度、官方文档等也是非常重要的指标!当然,这里仅仅是jackson功能的九牛一毛,更详细深入的学习需要到jackson官方文档去查阅。
现在三种java的序列化/反序列化json框架都已经介绍啦。三者都是非常优秀的框架,这是毋庸置疑的,但是一对比,它就有一些伤害啊(嘤嘤嘤)。
名称 | Gson | fastjson | Jackson |
---|---|---|---|
社区生态 | 较好 | 一般 | 较好 |
易用性 | 易用 | 易用 | 一般 |
小文件速度 | 最快 | 较快 | 较慢 |
大文件速度 | 较慢 | 较快 | 较快 |
稳定性 | 稳定 | 一般 | 稳定 |
安装包大小 | 非常小 | 较小 | 一般 |
综上所述来说:
Gson:轻便简洁,适合中小json文件的解析。在大json文件上效率略差,且其功能比较全面,生态较好。
jackson:处理大文件速度快一些,且比fastjson稳定一些。生态较好。
fastjson:速度较快,但经常爆出安全问题。生态一般,主要国内使用。
对选取哪个json框架主要根据自己的需要,如果是测试或者比较简单个人使用,推荐Gson和fastjson上手比较容易。如果是需要上线,那么fastjson得慎用,可能某些数据会序列化失败。
在介绍完的最后,偷偷赞扬一下咱们fastjson主要贡献者温少
,不仅是fastjson开源者温少也是另一开源框架主要贡献者—druid(阿里数据库连接池),所以这位作者大大是非常努力,将自己奉献给了开源的事业中,服务更多的人,点赞!!! 希望未来的我们,也能像温少那样有所作为!加油!
在这里,本篇对json得介绍、json语法使用以及Gson/fastjson/jackson的一些实战的介绍就此已经完毕了,json很容易,但json也可能很复杂,这要取决你具体业务的使用和需求,希望在日后的日子里,能够对json的理解和应用能够有更深一步的认知!加油,我们下次再见!
(单选)既然对比完Gson,fastjson,Jackson,那么小老弟妹们,俺来考考你对三者认识咋样,那么问题来了,你给我看看下面那个是错的呢?(B)
上面讲了那么多,对于我们来说掌握java中操作json很重要,那么咱们动手进行一个转换小案例。这里咱们要求用Gson,fastjson将下面对象进行转化:
javaBean转json字符串
假设我们有个teacher 类有name和age两个属性。
public class teacher {
private String name;
private int age;
//省略get set 以及构造函数
}
首先我们有一个对象
teacher teachersai=new teacher("bigsai",22);
大家想一下这个对象的json格式的字符串会是什么样的呢?
没错,答案就是这样的:
{"name":"bigsai","age":22}
如果是Gson,我们是这样操作的:
Gson gson=new Gson();
String teacherstr=gson.toJson(teachersai);
System.out.println(teacherstr);//{"name":"bigsai","age":22}
而如果是fastjson,它又会是怎样的呢?
String teacherstr=JSON.toJSONString(teachersai);
System.out.println(teacherstr);//{"name":"bigsai","age":22}
这样就完成java对象转成json字符串啦,是不是非常简单,因为fastjson将JSON中的很多方法写成静态static所以我们连这个对象都不需要创建。
json字符串转javaBean
上面咱们轻轻松松的就可以将javaBean转成json字符串,下面如果咱们有这么一个字符串需要转成java的teacher对象,需要怎么搞呢?
String teacherpian="{\"name\":\"bigpian\",\"age\":21}";//{"name":"bigpian","age":21}
那么创建完Gson对象只需一行代码就搞定:
Gson gson=new Gson();
teacher teacherp=gson.fromJson(teacherpian,teacher.class);
同理,咱们fastjson也是一行代码搞定:
teacher teacherp=JSON.parseObject(teacherpian,teacher.class);
是不是很容易呢?当然如果细心好学的你肯定会发现还有其他的写法啦,修行靠个人啦,更多的用法肯定还需要自己去挖掘啦!
轻松愉快的json介绍课程到这里就结束了,通过本节课程,你了解了json的概念,分清了json和xml的异同点,也知道了json在web领域和非关系数据库的那些应用。通过系列介绍、比较、结合实际场景相信你对json的认识肯定都是非常清晰。
紧接着文章又介绍了json的语法规则以及在java中操作json的实战操作,学习和比较了Gson、fastjson、jackson的应用以及他们之间的区别点,相信你也掌握了在java语言中json的实战能力,且能够根据自己需求灵活使用哪种框架,并深入的研究下去。
json是web技术进步与发展的产物,它是一种数据交换格式。它几乎是前后端程序员不可避免的技术点,希望大家在日后能够多多回顾课程,结合其他教材文本等,将json 从立地到成佛!加油,我们下次再会!
在这里插入图片描述
标签:年龄 单词 遵从 式表 treemap 除了 联系 print ocs
原文地址:https://www.cnblogs.com/bigsai/p/13223885.html