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

json,fastjson,Jackson,Gson区别对比_java

当然,如果你使用的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。

json,fastjson,Jackson,Gson区别对比_java_02

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当中,基本数据类型,即使不赋值,也有默认值)。

运行结果如下:

json,fastjson,Jackson,Gson区别对比_ide_03

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试试

json,fastjson,Jackson,Gson区别对比_json_04

执行结果:

json,fastjson,Jackson,Gson区别对比_JAVA_05

没有一点卵用,为什么呢?因为@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试试

json,fastjson,Jackson,Gson区别对比_json_06

执行结果:

json,fastjson,Jackson,Gson区别对比_json_07

我们可以看到:

虽然注解@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

JSONObject.boBean(JSONObject.fromObject(jsonStrs), Class);

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,fastjson,Jackson,Gson区别对比_json_08

 

我们可以看到:json字符串通过netjson转换是能够完完整整地对照上的。

com.alibaba.fastjson

JSONObject.parseObject(jsonStr, Class);

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());

json,fastjson,Jackson,Gson区别对比_JAVA_09

我们可以看到:通过fastjson转换的字符串也能完整对照上(映射不上的属性对应的值为null,如果是基本数据类型的话,有对应的默认值)。

com.fasterxml.jackson

new ObjectMapper().readValue(jsonStr, Class);

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();
}

json,fastjson,Jackson,Gson区别对比_ide_10

属性名称和key可以完全对照上,属性值和value也能完全比对上。

com.google.gson

new Gson().fromJson(jsonStr, Class);

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());

json,fastjson,Jackson,Gson区别对比_java_11

和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);

json,fastjson,Jackson,Gson区别对比_java_12

 

com.alibaba.fastjson

JSONArray.toJSON(list/array);

String fastjsonStrs = com.alibaba.fastjson.JSONArray.toJSON(peopleList).toString();
System.out.println("javas-->fastjsonStrs" + fastjsonStrs);

json,fastjson,Jackson,Gson区别对比_ide_13

 

com.fasterxml.jackson

new ObjectMapper().writeAsString(list/array) ;

String jacksonStrs = new ObjectMapper().writeValueAsString(peopleList);
System.out.println("javas-->jacksonStrs" + jacksonStrs);

json,fastjson,Jackson,Gson区别对比_ide_14

 

com.google.gson

new Gson().toJson(list/array) ;

String gsonStrs = new Gson().toJson(peopleList);
System.out.println("javas-->gsonStrs" + gsonStrs);

json,fastjson,Jackson,Gson区别对比_ide_15

 

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);

json,fastjson,Jackson,Gson区别对比_ide_16

 

com.alibaba.fastjson

JSONArray.parseArray(fastjsonStrs, Class);

List<People> fastPeopleList = JSONArray.parseArray(fastjsonStrs, People.class);
System.out.println("fastjsonStrs-->javas" + fastPeopleList);

json,fastjson,Jackson,Gson区别对比_json_17

 

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);

json,fastjson,Jackson,Gson区别对比_java_18

 

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);

json,fastjson,Jackson,Gson区别对比_json_19

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

  • ​​个人主页​​
  • ​​java json对象转json字符串(带转义符)(json对象嵌套json字符串)​​
  • ​​gson 反序列化,整数变小数的终极解决方案​​

作者:​​Marydon