json,fastjson,Jackson,Gson区别对比
1.情景展示
在javaWeb开发过程中,我目前遇到的json类型一共有4种,它们分别是:
json,fastjson,Jackson和Gson,下面介绍它们的区别。
2.基本介绍
net.sf.json
查看代码
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<!--ezmorph(它还依赖了commons-lang)-->
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<!--commons-beanutils(它还依赖了commons-logging-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.0</version>
</dependency>
不仅需要json的jar包,还需要引入它所依赖的其它5个jar包:commons-beanutils-1.7.0.jar commons-collections-3.1.jar commons-lang-2.5.jar commons-logging.jar ezmorph-1.0.3.jar
当然,如果你使用的maven的话,只需引入上面那4个就行了,其余所需依赖,maven会自动帮我们下载到本地仓库。
com.alibaba.fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.9</version>
</dependency>
com.fasterxml.jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2</version>
</dependency>
依赖的jar包:jackson-core.jar和jackson-annotations.jar。
com.google.gson
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
3.分析对比
先准备实体类People.java
查看代码
/**
* 实体类
* @description:
* @author: Marydon
* @date: 2022-03-18 17:13
* @version: 1.0
* @email: marydon20170307@163.com
*/
public class People {
private String HR;
private int QRSaxis;
private String P;
private String slideID;
private Integer RV5;
private String TEST;
private BigDecimal myAge;
private boolean flag;
public String getHR() {
return HR;
}
public void setHR(String HR) {
this.HR = HR;
}
public int getQRSaxis() {
return QRSaxis;
}
public void setQRSaxis(int QRSaxis) {
this.QRSaxis = QRSaxis;
}
public String getP() {
return P;
}
public void setP(String p) {
P = p;
}
public String getSlideID() {
return slideID;
}
public void setSlideID(String slideID) {
this.slideID = slideID;
}
public String getTEST() {
return TEST;
}
public void setTEST(String TEST) {
this.TEST = TEST;
}
public Integer getRV5() {
return RV5;
}
public void setRV5(Integer RV5) {
this.RV5 = RV5;
}
public BigDecimal getMyAge() {
return myAge;
}
public void setMyAge(BigDecimal myAge) {
this.myAge = myAge;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public People() {
}
public People(String HR, int QRSaxis, String p, String slideID, int RV5, String TEST) {
this.HR = HR;
this.QRSaxis = QRSaxis;
P = p;
this.slideID = slideID;
this.RV5 = RV5;
this.TEST = TEST;
}
}
3.1 java对象转JSON对象(序列化)
People people = new People("HR", 18, "P", "slideID", 5, null);
System.out.println("java-->netjson" + net.sf.json.JSONObject.fromObject(people));
System.out.println("java-->gson" + new Gson().toJson(people));
System.out.println("java-->fastjson" + com.alibaba.fastjson.JSONObject.toJSON(people));
try {
System.out.println("java-->jackson" + new ObjectMapper().writeValueAsString(people));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
people对象现在已知的属性为:HR=HR,QRSaxis=18,P=p,slideID=slideID,RV5=5,TEST=null(java当中,基本数据类型,即使不赋值,也有默认值)。
运行结果如下:
net.sf.json
{"HR":"HR","QRSaxis":18,"RV5":5,"TEST":"","flag":false,"myAge":0,"p":"P","slideID":"slideID"}
第一,属性名称:
我们可以看到除了P被转成小写以外,其余key是完全按照字段名称来转换的。换句话说,只要是属性名称不是有且只有一个大写的英文字母,它就可以实现完全按照字段名称完成key的序列化。
第二,属性值。
String类型的TEST,我们给它赋的值是null,而json将它的值,设置成了String类型的空值,即"";
BigDecimal类型的myAge,没有指定该属性的属性值,json给它赋成了0。
小结:
在使用该json对象完成序列化的时候,不管我们有没有给类的属性赋值,类的属性都将会被序列化成key,并会为其设置对应的值。
com.alibaba.fastjson
{"p":"P","rV5":5,"slideID":"slideID","flag":false,"hR":"HR","qRSaxis":18}
我们可以看到:在fastjson中,属性名称的首字母大写,是不被允许的。
如果我们大写,在序列化的时候,会被强制转成小写。
属性值TEST属性被我们指定成了null,myAge我们没有指定,fastjson没有将二者序列化出来;
换句话说就是:当我们没有为属性设定值,或者将属性值设置成null的话,则该属性将不会被序列化出来。
能不能解决序列化时,导致名称可能不一致的情况?
用@JsonField试试
执行结果:
没有一点卵用,为什么呢?因为@JSONField注解只能进行反序列化,对序列化无效。
com.fasterxml.jackson
{"slideID":"slideID","myAge":null,"flag":false,"p":"P","test":null,"hr":"HR","qrsaxis":18,"rv5":5}
我们可以看到:在jackson中,属性名称不能以大写开头,一旦被检测出来,第一个字母是大写,它会一直往后检索,直到检索到属性名称当中的字母是小写才会停止;
也就是说,当首字母是大写时,后面的紧挨着它的也是大写时,会实行连坐制,统统强制转换成小写,比fastjson更暴力。
属性值TEST属性被我们指定成了null,myAge我们没有指定,但是,会被jackson序列化出来。
jackjson也会像netjson一样,将类的全部属性序列化出来,如果没有赋值,或者值为null,序列化出来key对应的值就是null(基本数据类型除外)。
能不能解决序列化时,导致名称可能不一致的情况?
用@JsonProperty试试
执行结果:
我们可以看到:
虽然注解@JsonProperty可以实现属性名称的序列化映射,但是,它只是在原来数据的基础之上,进行追加;
对于这样的效果,显然达不到我们的要求,但在这点上,起码比fastjson强上一点。
com.google.gson
{"HR":"HR","QRSaxis":18,"P":"P","slideID":"slideID","RV5":5,"flag":false}
我们可以看到:gson在序列化的时候,序列化后的key名称,将会完全遵照属性名称的大小写来进行。
另外,和fastjson一样,当属性值为null或者没有指定该属性对应的值时,该属性不会被序列化出来(八种基本数据类型除外)。
3.2 json字符串转java对象(反序列化)
准备工作:为People类生成toString()方法。
查看代码
@Override
public String toString() {
return "People{" +
"HR='" + HR + '\'' +
", QRSaxis=" + QRSaxis +
", P='" + P + '\'' +
", slideID='" + slideID + '\'' +
", RV5=" + RV5 +
", TEST='" + TEST + '\'' +
", myAge=" + myAge +
", flag=" + flag +
'}';
}
net.sf.json
People people = new People("HR", 18, "P", "slideID", 5, null);
String netJsonStr = net.sf.json.JSONObject.fromObject(people).toString();
System.out.println("java-->netJsonStr" + netJsonStr);
People netPeople = (People) net.sf.json.JSONObject.toBean(net.sf.json.JSONObject.fromObject(netJsonStr), People.class);
System.out.println("netJsonStr-->java" + netPeople.toString());
我们可以看到:json字符串通过netjson转换是能够完完整整地对照上的。
com.alibaba.fastjson
String fastjson = com.alibaba.fastjson.JSONObject.toJSON(people).toString();
System.out.println("java-->fastjson" + fastjson);
People fastPeople = JSONObject.parseObject(fastjson, People.class);
System.out.println("fastjson-->java" + fastPeople.toString());
我们可以看到:通过fastjson转换的字符串也能完整对照上(映射不上的属性对应的值为null,如果是基本数据类型的话,有对应的默认值)。
com.fasterxml.jackson
try {
String jacksonStr = new ObjectMapper().writeValueAsString(people);
System.out.println("java-->jacksonStr" + jacksonStr);
ObjectMapper objectMapper = new ObjectMapper();
People jackPeople = objectMapper.readValue(jacksonStr, People.class);
System.out.println("jacksonStr-->java" + jackPeople);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
属性名称和key可以完全对照上,属性值和value也能完全比对上。
com.google.gson
String gsonStr = new Gson().toJson(people);
System.out.println("java-->gsonStr" + gsonStr);
People gsonPeople = new Gson().fromJson(gsonStr, People.class);
System.out.println("gsonStr-->java" + gsonPeople.toString());
和fastjson一样,能够完全反序列化。
3.3 java数组转json数组
net.sf.json
JSONArray.fromObject(list/array/javaBean);
List<People> peopleList = new ArrayList<>(1);
People people = new People("HR", 18, "P", "slideID", 5, null);
peopleList.add(people);
String netJsonStrs = net.sf.json.JSONArray.fromObject(peopleList).toString();
System.out.println("javas-->netJsonStrs" + netJsonStrs);
com.alibaba.fastjson
JSONArray.toJSON(list/array);
String fastjsonStrs = com.alibaba.fastjson.JSONArray.toJSON(peopleList).toString();
System.out.println("javas-->fastjsonStrs" + fastjsonStrs);
com.fasterxml.jackson
new ObjectMapper().writeAsString(list/array) ;
String jacksonStrs = new ObjectMapper().writeValueAsString(peopleList);
System.out.println("javas-->jacksonStrs" + jacksonStrs);
com.google.gson
new Gson().toJson(list/array) ;
String gsonStrs = new Gson().toJson(peopleList);
System.out.println("javas-->gsonStrs" + gsonStrs);
3.4json数组转java数组
net.sf.json
JSONArray.toCollection(JSONArray, Class);
List<People> netPeopleList = (List<People>) net.sf.json.JSONArray.toCollection(net.sf.json.JSONArray.fromObject(netJsonStrs), People.class);
System.out.println("netJsonStrs-->javas" + netPeopleList);
com.alibaba.fastjson
JSONArray.parseArray(fastjsonStrs, Class);
List<People> fastPeopleList = JSONArray.parseArray(fastjsonStrs, People.class);
System.out.println("fastjsonStrs-->javas" + fastPeopleList);
com.fasterxml.jackson
ObjectMapper objectMapper = new ObjectMapper();
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, People.class);
objectMapper.readValue(jacksonStrs, javaType);
ObjectMapper objectMapper = new ObjectMapper();
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, People.class);
List<People> jackPeopleList = objectMapper.readValue(jacksonStrs, javaType);
System.out.println("jacksonStrs-->javas" + jackPeopleList);
com.google.gson
new Gson().fromJson(gsonStrs, new TypeToken<List<javaBean>>(){}.getType());
List<People> gsonPeopleList = new Gson().fromJson(gsonStrs, new TypeToken<List<People>>(){}.getType());
System.out.println("gsonStrs-->javas" + gsonPeopleList);
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
相关推荐:
原文地址:https://www.cnblogs.com/Marydon20170307/p/16045381.html
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(3)
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(2)
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)
- element-ui el-input只显示下划线
- 怎样去阅读源码,这篇文章值的你一读
- HTML5 Blob与ArrayBuffer、TypeArray和字符串String之间转换
- Mybatis 3 配置 Log4j
- 基于Three.js的360度全景--photo-sphere-viewer--简介
- MyBatis3-配置使用log4j输出日志
- nginx支持跨域访问
- nginx静态资源文件无法访问,403 forbidden错误
- vue.js如何在标签属性中插入变量参数
- SpringBoot解决ajax跨域问题
- WebBrowser(IE) 与 JS 相互调用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 线程池ThreadPoolExecutor 源码分析,面试官也就那么回事,他怎么敢!
- Spug - 轻量级自动化运维平台
- Callable/Future 使用及原理分析,Future .get()为啥能等待呢?
- 优雅的drop掉mysql库中1TB大表
- 《剑指offer》第19天:股票交易(校对)
- SwiftyUserDefaults-封装系统本地化的框架推荐
- “使用多target来构建大量相似App”,唐巧大神理论验证(附工程代码地址)
- 小结:Swift、OC语言中多target在代码中如何区分
- 点击按钮每次都能实现图片的旋转和切换(swift)
- 多线程之NSOperation小结
- 判断一个坐标点是否在封闭曲线内的方法(swift)
- OC循环方法推荐-块循环遍历(比for循环好用)
- oc工程中oc、swift混编代码打包成静态framework踩坑笔记
- alloc 和 init都做了什么验证。
- 回顾冒泡排序(新增优化代码)