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

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

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM