前言:json是现在非常流程的数据交换格式,所以对于被开发人员来说如何更好了解java对象和json格式之间的转换是至关重要的,接下来我们来好好说一说。
一、什么是JSON(摘自百度百科)
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
传统的我们使用比较多的是XML格式,那么两者之间的区别又是什么呢?
JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。
XML天生有很好的扩展性,JSON当然也有,没有什么是XML可以扩展而JSON却不能扩展的。不过JSON在Javascript主场作战,可以存储Javascript复合对象,有着xml不可比拟的优势。
XML有丰富的编码工具,比如Dom4j、Dom、SAX等,JSON也有提供的工具。无工具的情况下,相信熟练的开发人员一样能很快的写出想要的xml文档和JSON字符串,不过,xml文档要多很多结构上的字符。
XML的解析方式有两种:
一是通过文档模型解析,也就是通过父标签索引出一组标记。例如:xmlData.getElementsByTagName("tagName"),但是这样是要在预先知道文档结构的情况下使用,无法进行通用的封装。
另外一种方法是遍历节点(document 以及 childNodes)。这个可以通过递归来实现,不过解析出来的数据仍旧是形式各异,往往也不能满足预先的要求。
凡是这样可扩展的结构数据解析起来一定都很困难。
JSON也同样如此。如果预先知道JSON结构的情况下,使用JSON进行数据传递简直是太美妙了,可以写出很实用美观可读性强的代码。如果你是纯粹的前台开发人员,一定会非常喜欢JSON。但是如果你是一个应用开发人员,就不是那么喜欢了,毕竟xml才是真正的结构化标记语言,用于进行数据传递。
而如果不知道JSON的结构而去解析JSON的话,那简直是噩梦。费时费力不说,代码也会变得冗余拖沓,得到的结果也不尽人意。但是这样也不影响众多前台开发人员选择JSON。因为json.js中的toJSONString()就可以看到JSON的字符串结构。当然对于不是经常使用这个字符串的人,这样做仍旧是噩梦。常用JSON的人看到这个字符串之后,就对JSON的结构很明了了,就更容易的操作JSON。
以上是在Javascript中仅对于数据传递的xml与JSON的解析。在Javascript地盘内,JSON毕竟是主场作战,其优势当然要远远优越于xml。如果JSON中存储Javascript复合对象,而且不知道其结构的话,我相信很多程序员也一样是哭着解析JSON的。
除了上述之外,JSON和XML还有另外一个很大的区别在于有效数据率。JSON作为数据包格式传输的时候具有更高的效率,这是因为JSON不像XML那样需要有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输压力 [2] 。
XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。
用XML表示中国部分省市数据如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
用JSON表示如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
可以看到,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用的带宽。
二、java中常用的JSON工具包
json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,
包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
对于复杂类型的转换,json-lib对于json转换成bean还有缺陷,比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。
json-lib在功能和性能上面都不能满足现在互联网化的需求。
相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。
而且Jackson社区相对比较活跃,更新速度也比较快。
Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。
Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式
Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,
但自从在2008年五月公开发布第一版后已被许多公司或用户应用。
Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。
而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。
类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。
Gson在功能上面无可挑剔,但是性能上面比FastJson有所差距。
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。
无依赖,不需要例外额外的jar,能够直接跑在JDK上。
FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。
FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
综上4种Json技术的比较,在项目选型的时候可以使用Google的Gson和阿里巴巴的FastJson两种并行使用,
如果只是功能要求,没有性能要求,可以使用google的Gson,如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean。
接下来就来看看具体的代码吧.............
三、代码实战
1、导入Maven依赖
com.google.code.gson
gson
2.8.0
com.alibaba
fastjson
1.1.22
2、创建java对象(注意添加Lombok组件)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyObject {
private String name;
private Integer age;
private String address;
private Date createTime;
}
3.Gson使用说明
package com.example.demo.huyue.Json;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author
*/
public class GsonDemo {
public static void main(String[] args) {
Gson gson = new Gson();
//1.bean转json
MyObject object = new MyObject();
object.setName("山山来驰");
object.setAge(19);
object.setAddress("中国上海");
System.out.println("bean转json=====>" + gson.toJson(object));
//2.json转bean
String jsonString = "{\"name\":\"山山来驰\",\"age\":19,\"address\":\"中国上海\"}";
System.out.println("json转bean=====>" + gson.fromJson(jsonString, MyObject.class));
//3.json转换复杂的bean,比如List,Set
jsonString = "[{\"name\":\"山山来驰\",\"age\":19,\"address\":\"中国上海\"},{\"name\":\"土地孙\",\"age\":100,\"address\":\"美国硅谷\"}]";
System.out.println("json转换复杂的bean List=====>" + gson.fromJson(jsonString, new TypeToken>() {
}.getType()).toString());
System.out.println("json转换复杂的bean Set=====>" + gson.fromJson(jsonString, new TypeToken>() {
}.getType()).toString());
//4.通过json对象直接操作json以及一些json的工具
//4.1格式化Json
gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(jsonString);
System.out.println("格式化Json=====>" + gson.toJson(element));
//4.2判断字符串是否是json,通过捕捉的异常来判断是否是json
try {
new JsonParser().parse(jsonString).getAsJsonObject();
System.out.println("判断是否是json=====>" + true);
} catch (Exception e) {
System.out.println("判断是否是json=====>" + false);
}
//4.3从json串中获取属性
jsonString = "{\"name\":\"山山来驰\",\"age\":19,\"address\":\"中国上海\"}";
try {
System.out.println("从json串中获取属性=====>" + new JsonParser().parse(jsonString).getAsJsonObject().get("name").toString());
} catch (Exception e) {
System.out.println("从json串中获取属性=====>" + null);
}
//4.4去除json中的某个属性
System.out.println("去除json中的某个属性=====>" + new JsonParser().parse(jsonString).getAsJsonObject().remove("name").toString());
//4.5向json中添加属性
new JsonParser().parse(jsonString).getAsJsonObject().addProperty("phone", new Gson().toJson("18355191886"));
System.out.println("向json中添加属性=====>" + jsonString);
//4.6修改json中的属性
JsonObject jsonObject = new JsonParser().parse(jsonString).getAsJsonObject();
jsonObject.remove("address");
jsonObject.addProperty("address", new Gson().toJson("中国北京"));
System.out.println("修改json中的属性=====>" + jsonString);
//4.7判断json中是否有属性
System.out.println("判断json中是否有属性=====>" + new JsonParser().parse(jsonString).getAsJsonObject().has("address"));
//4.8json中日期格式的处理
gson = new GsonBuilder().setDateFormat("yyyyMMddHHmmssSSS").create();
MyObject myObject = new MyObject();
myObject.setName("二郎神");
myObject.setAge(101);
myObject.setAddress("南天门");
myObject.setCreateTime(new Date());
System.out.println("json中日期格式的处理=====>" + gson.toJson(myObject));
}
}
4、FastJson使用说明
package com.example.demo.huyue.Json;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import sun.nio.cs.ext.JIS_X_0212_Solaris;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author
*/
public class FastGsonDemo {
public static void main(String[] args) {
//1.bean转换json
//1.1将对象转换成格式化的json
MyObject myObject = new MyObject();
myObject.setName("李寻欢");
myObject.setAge(31);
myObject.setAddress("天上人间");
myObject.setCreateTime(new Date());
System.out.println("将对象转换成格式化的json=====>" + JSON.toJSONString(myObject, true));
//1.2将对象转换成非格式化的json
System.out.println("将对象转换成非格式化的json=====>" + JSON.toJSONString(myObject, false));
//1.3数组转json
List list = new ArrayList<>(16);
MyObject myObject1 = new MyObject("东邪", 56, "桃花岛", new Date());
MyObject myObject2 = new MyObject("西毒", 55, "西方极乐世界", new Date());
MyObject myObject3 = new MyObject("南帝", 60, "皇宫大院", new Date());
MyObject myObject4 = new MyObject("北丐", 70, "丐帮", new Date());
list.add(myObject1);
list.add(myObject2);
list.add(myObject3);
list.add(myObject4);
System.out.println("数组转json=====>" + JSON.toJSONString(list));
//2.json转bean
String jsonString = "{\"address\":\"天上人间\",\"age\":31,\"createTime\":1556693449741,\"name\":\"李寻欢\"}";
System.out.println("json转bean=====>" + JSON.parseObject(jsonString, MyObject.class));
//3.json转复杂bean
jsonString = "[{\"address\":\"桃花岛\",\"age\":56,\"createTime\":1556693450022,\"name\":\"东邪\"},{\"address\":\"西方极乐世界\",\"age\":55,\"createTime\":1556693450022,\"name\":\"西毒\"},{\"address\":\"皇宫大院\",\"age\":60,\"createTime\":1556693450022,\"name\":\"南帝\"},{\"address\":\"丐帮\",\"age\":70,\"createTime\":1556693450022,\"name\":\"北丐\"}]";
System.out.println("json转复杂bean======>" + JSON.parseObject(jsonString, new TypeReference>() {
}));
//4.通过json对象直接操作json
//4.1从json串中获取属性
jsonString = "{\"address\":\"天上人间\",\"age\":31,\"createTime\":1556693449741,\"name\":\"李寻欢\"}";
System.out.println("从json串中获取属性=====>" + JSON.parseObject(jsonString).get("name"));
//4.2除去json中的某个属性
JSONObject jsonObject = JSON.parseObject(jsonString);
jsonObject.keySet().remove("name");
System.out.println("除去json中的某个属性=====>" + jsonObject.toString());
//4.3向json中添加属性
jsonObject.put("name", JSON.toJSONString("江南七怪"));
System.out.println("向json中添加属性=====>" + jsonObject.toString());
//4.4修改json中的属性
if (jsonObject.keySet().contains("address")) {
jsonObject.put("address", JSON.toJSONString("地下人间"));
}
System.out.println("修改json中的属性=====>" + jsonObject.toString());
//4.5判断json中是否有属性
System.out.println("判断json中是否有属性======>" + jsonObject.keySet().contains("createTime"));
//4.6json中日期格式的处理
MyObject object = new MyObject("孙悟空", 22, "花果山", new Date());
System.out.println("json中日期格式的处理=====>" + JSON.toJSONStringWithDateFormat(object, "yyyyMMddHHmmssSSS"));
}
}
四、总结
目前使用的基本都是基于Gson和FastJson,以后可能会有更好用的组件,一定要坚持学习,这样才不会被淘汰。
参考地址:https://blog.csdn.net/jason201710/article/details/78657469