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
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字符串通過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());
我們可以看到:通過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();
}
屬性名稱和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());
和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);
寫在最后
哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!