Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> json相關類庫,java對象與json相互轉換,json相互轉換

json相關類庫,java對象與json相互轉換,json相互轉換

編輯:關於android開發

json相關類庫,java對象與json相互轉換,json相互轉換


有效選擇七個關於Java的JSON開源類庫

轉自:http://www.open-open.com/lib/view/open1397870197828.html

翻譯:

 (英語原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-available-today.html)

 簡介

JSON是JavaScript Object Notation的縮寫,是一種輕量級的數據交換形式,是一種XML的替代方案,而且比XML更小,更快而且更易於解析。因為JSON描述對象的時候使用的是JavaScript語法,它是語言和平台獨立的,並且這些年許多JSON的解析器和類庫被開發出來。在這篇文章中,我們將會展示7種Java JSON類庫。基本上,我們將會試著把Java對象轉換JSON格式並且存儲到文件,並且反向操作,讀JSON文件轉換成一個對象。為了讓文章更有意義,我們將會測量每一種JSON類庫在不同情況下的處理速度。

 (一)類庫介紹及其使用

1)使用Jackson類庫

第一個介紹的是Jackson類庫,Jackson庫是一個“旨在為開發者提供更快,更正確,更輕量級,更符合人性思維” 的類庫。Jackson為處理JSON格式提供了三種模型的處理方法。

1、流式API或者增量解析/產生( incremental parsing/generation):讀寫JSON內容被作為離散的事件。

2、樹模型:提供一個可變內存樹表示JSON文檔。

3、數據綁定(Data binding):實現JSON與POJO(簡單的Java對象(Plain Old Java Object))的轉換

我們感興趣的是Java對象與JSON的轉換,因此,我們將集中於第三種處理方法。首先我們 需要下載Jackson。Jackson的核心功能使用三個類庫,分別是jackson-core-2.3.1, jackson-databind- 2.3.1和jackson-annotations-2.3.1; 三個類庫的下載都來自於Maven倉庫,給出地址:

http://repo1.maven.org/maven2/com/fasterxml/jackson/ 

(譯者注:在http://repo1.maven.org/maven2/com/fasterxml/jackson/core/中,正好是三個類庫的文件夾)

現在,讓我們來工作吧,為了從Java對象中獲得一個一個復雜的JSON對象,我們將會使用下面的類去構造一個對象。同樣的Java對象將會被用於這篇文章的所有的類庫中。

public class JsonThirdObject {

 

          private int age = 81;

          private String name = "Michael Caine";

          private List<String> messages;

 

          public JsonThirdObject() {

            this.messages = new ArrayList<String>() {

                    {

                              add("You wouldn't hit a man with no trousers..");

                              add("At this point, I'd set you up with a..");

                              add("You know, your bobby dangler, giggle stick,..");

                              }

                    };

          }

          // Getter and setter

}

 

public class JsonSecondObject {

 

          private int age = 83;

          private String name = "Clint Eastwood";

          private JsonThirdObject jsnTO = new JsonThirdObject();

          private List<String> messages;

 

          public JsonSecondObject() {

            this.messages = new ArrayList<String>() {

                    {

                              add("This is the AK-47 assault..");

                              add("Are you feeling lucky..");

                              add("When a naked man's chasing a..");

                              }

                    };

          }

          // Getter and setter

}

 

public class JsonFirstObject {

 

          private int age = 76;

          private String name = "Morgan Freeman";

          private JsonSecondObject jsnSO = new JsonSecondObject();

          private List<String> messages;

 

          public JsonFirstObject() {

            this.messages = new ArrayList<String>() {

                    {

                              add("I once heard a wise man say..");

                              add("Well, what is it today? More..");

                              add("Bruce... I'm God. Circumstances have..");

                              }

                    };

          }

          // Getter and setter

}

 

public class Json {

 

          private int age = 52;

          private String name = "Jim Carrey";

          private JsonFirstObject jsnFO = new JsonFirstObject();

          private List<String> messages;

 

          public Json() {

            this.messages = new ArrayList<String>() {

                    {

                              add("Hey, maybe I will give you..");

                              add("Excuse me, I'd like to..");

                              add("Brain freeze. Alrighty Then I just..");

                              }

                    };

          }

          // Getter and setter

}

上面的Java對象轉換成JSON格式是下面這樣的。

{

   "age":52,

   "name":"Jim Carrey",

   "jsnFO":{

      "age":76,

      "name":"Morgan Freeman",

      "jsnSO":{

         "age":83,

         "name":"Clint Eastwood",

         "jsnTO":{

            "age":81,

            "name":"Michael Caine",

            "messages":[

               "You wouldn't hit a man..",

               "At this point, I'd set you..",

               "You know, your bobby dangler.."

            ]

         },

         "messages":[

            "This is the AK-47 assault..",

            "Are you feeling lucky..",

            "When a naked man's chasing a.."

         ]

      },

      "messages":[

         "I once heard a wise man..",

         "Well, what is it today? More..",

         "Bruce... I'm God. Circumstances have.."

      ]

   },

   "messages":[

      "Hey, maybe I will give you a call..",

      "Excuse me, I'd like to ask you a few..",

      "Brain freeze. Alrighty Then I just heard.."

   ]

}

現在,讓我們來看看怎麼樣把Java對象轉換成JSON並且寫入文件。Jackson使用一個ObjectMapper功能,我們第一步要做的是:

 

Json jsonObj = new Json();

ObjectMapper mapper = new ObjectMapper();

然後,我們將會使用這個ObjectMapper直接寫入值到文件。

 

System.out.println("Convert Java object to JSON format and save to file");

try {

     mapper.writeValue(new File("c:\\jackson.json"), jsonObj);

} catch (JsonGenerationException e) {

} catch (JsonMappingException e) {

} catch (IOException e) {

}

現在,我們有了一個JSON文件,但是,怎麼樣轉回Java對象呢?我們可以這樣做:

 

System.out.println("Read JSON from file, convert JSON back to object");

try {

     jsonObj = mapper.readValue(new File("c:\\jackson.json"), Json.class);

} catch (JsonGenerationException e) {

} catch (JsonMappingException e) {

} catch (IOException e) {

}

從上面的例子我們知道了JSON和Java對象的相互轉換,在try-catch中總共也就兩行,看起來不錯是吧,但是它快麼?我們將會在後面的文章中揭曉。

 (2)使用 Google-Gson類庫

第二種就是 Google-Gson,我們立即開始討論 Gson,你或許更喜歡他的全名Google-Gson。Gson能實現Java對象和JSON之間的相互轉換。甚至都不需要注釋。Gson的特點:

1)提供簡單的toJson()方法和fromJson()去實現相互轉換。

2)可以從JSON中轉換出之前存在的不可改變的對象。

3)擴展提供了Java泛型。

4)支持任意復雜的對象。

Gson就需要一個.jar文件,gson-2.2.4.jar,可以通過http://code.google.com/p/google-gson/downloads/list下載。下面是例子,把Java對象轉換成JSON。

 

Json jsonObj = new Json();

Gson gson = new Gson();

 

System.out.println("Convert Java object to JSON format and save to file");

try (FileWriter writer = new FileWriter("c:\\gson.json")) {

     writer.write(gson.toJson(jsonObj));

} catch (IOException e) {

}

JSON轉換成Java對象:

 

System.out.println("Read JSON from file, convert JSON string back to object");

try (BufferedReader reader = new BufferedReader(new FileReader("c:\\gson.json"))) {

   jsonObj = gson.fromJson(reader, Json.class);

} catch (FileNotFoundException e) {

} catch (IOException e) {

}

 

上面就是我們所有需要做的,接下來我們可以對 jsonObj 作進一步處理。當調用JSON操作的時候,因為Gson的實例化對象沒有維持任何狀態,我們可以重復使用一個對象為多個JSON序列化和反序列化操作。

(3)使用JSON-lib類庫

JSON-lib類庫是基於Douglas Crockford的工作成果,能轉換bean,map,集合(collection),java數組和XML轉換成JSON並能反向轉換成beans和動態bean(DynaBean)。JSON-lib類庫的下載地址:http://sourceforge.net/projects/json-lib/files/ 下面這些是依賴文件

· jakarta commons-lang 2.6

· jakarta commons-beanutils 1.9.1

· jakarta commons-collections 3.2.1

· jakarta commons-logging 1.1.3

· ezmorph 1.0.6

(譯者注:Douglas CrockfordWeb開發領域最知名的技術權威之一,ECMA JavaScript2.0標准化委員會委員。被JavaScript之父Brendan Eich稱為JavaScript的大宗師(Yoda)。曾任Yahoo!資深JavaScript架構師,現任PayPal高級JavaScript架構師。他是JSONJSLintJSMinADSafe的創造者,也是名著《JavaScript: The Good Parts》(中文版《JavaScript語言精粹》)的作者。撰寫了許多廣為流傳、影響深遠的技術文章,包括“JavaScript:世界上最被誤解的語言”。Douglas Crockford曾在著名的Lucasfilm電影公司任技術總監;在Paramount(派拉蒙)公司任新媒體高級總監;communities社區創始人兼CEOState軟件公司CTO2012.05.14Paypal宣布Douglas Crockford加入Paypal)

同樣,讓我們來把Java對象轉成JSON。

 

Json jsonObj = new Json();

JSONObject json;

System.out.println("Convert Java object to JSON format and save to file");

try (FileWriter writer = new FileWriter("c:\\json-lib.json")) {

          json = JSONObject.fromObject(jsonObj);

          json.write(writer);

} catch (IOException e) {

}

 

JSON轉Java對象

 

System.out.println("Read JSON from file, convert JSON string back to object");

try (BufferedReader reader = new BufferedReader(new FileReader("c:\\json-lib.json"))) {

          jsonObj = (Json) JSONObject.toBean(JSONObject.fromObject(reader), Json.class);

} catch (IOException ex) {

}

這裡有個問題,這些依賴關系會影響到性能嗎?文章在下面揭曉。

 4)使用Flexjson類庫

Flexjson是 一個輕量級的庫,能序列化和反序列化Java對象和JSON,允許深層和淺層對象的拷貝。深度拷貝意味著一個被Flexjson序列化的對象,它能讓對象 做到類似於延遲加載(lazy-loading)的技術,能讓我們在對對象有需要時才提取。當我們想把整個對象寫入到文件時,這不是一個好的情況,但是它 知道需要才去做時,這是很好的。

Flexjson下載地址:http://sourceforge.net/projects/flexjson/files/ 它不需要其他庫就可以工作。下面是例子:Java對象轉JSON。

 

Json jsonObj = new Json();

JSONSerializer serializer = new JSONSerializer();

System.out.println("Convert Java object to JSON format and save to file");

try (FileWriter writer = new FileWriter("c:\\flexjson.json")) {

          serializer.deepSerialize(jsonObj, writer);

} catch (IOException e) {

}

 

JSON轉Java對象

 

System.out.println("Read JSON from file, convert JSON string back to object"); 

try (BufferedReader reader = new BufferedReader(new FileReader("c:\\flexjson.json"))){ 

    jsonObj = new JSONDeserializer<Json>().deserialize(reader); 

} catch (FileNotFoundException e) {

} catch (IOException e) { 

}

簡單有效是吧!

5)使用Json-io類庫

json-io有 兩個主要的類,一個讀和一個寫,排除了使用ObjectInputStream和 ObjectOutputStream兩個類去讀寫。Json-io能 序列化任意的Java對象圖(graph)轉變成JSON,並且能記憶完整的語義圖(graph semantics)和對象類型。下載地址: Maven Central Repository

它不需要其他依賴。

例子:Java對象轉JSON

 

Json jsonObj = new Json();

System.out.println("Convert Java object to JSON format and save to file");

try (JsonWriter writer = new JsonWriter(new FileOutputStream("c:\\json-io.json"))){

          writer.write(jsonObj);

} catch (IOException e) {

}

 

JSON轉Java對象

 

System.out.println("Read JSON from file, convert JSON string back to object");

try (JsonReader reader = new JsonReader(new FileInputStream(new File("c:\\json-io.json")))) {

          jsonObj = (Json) reader.readObject();

} catch (FileNotFoundException e) {

} catch (IOException e) {

}

 

它的文檔上說,Json-io比JDK的ObjectInputStream 和ObjectOutputStream的序列化操作要快,我們將會在後面的文章中說明。

6)使用Genson類庫

Genson是一個可擴展的,可伸縮的,易於使用的開源庫。除此之外,Genson完整支持了泛型,支持JSON在JAX-RS的實現,支持JAXB的注釋(annotation)和類型(types),並且允許序列化和反序列化擁有復雜關鍵字的map。

下載地址:http://code.google.com/p/genson/downloads/list ,它沒有任何依賴。

例子:Java對象轉JSON

 

Json jsonObj = new Json();

Genson genson = new Genson();

System.out.println("Convert Java object to JSON format and save to file");

try (FileWriter writer = new FileWriter("c:\\genson.json")) {

          writer.write(genson.serialize(jsonObj));

} catch (IOException | TransformationException e) {

}

JSON轉Java對象

 

System.out.println("Read JSON from file, convert JSON string back to object");

try (BufferedReader reader = new BufferedReader(new FileReader("c:\\genson.json"))) {

          jsonObj = genson.deserialize(reader, Json.class);

} catch (FileNotFoundException e) {

} catch (IOException | TransformationException e) {

}

 

(7)使用JSONiJ類庫

最後一個討論的是JSONiJ。JSONiJ是JSON的解析器,一個JPath和Marshaller的實現,能實現Java對象和JSON的相互轉換。下載地址:https://bitbucket.org/jmarsden/jsonij/downloads

它不需要任何依賴。

例子:Java對象轉JSON

 

Json jsonObj = new Json();

System.out.println("Convert Java object to JSON format and save to file");

try (FileWriter writer = new FileWriter("c:\\jsonij.json")) {

          writer.write(JSONMarshaler.marshalObject(jsonObj).toJSON());

} catch (IOException | JSONMarshalerException e) {

}

 

 

 

JSON轉Java 對象

System.out.println("Read JSON from file, convert JSON string back to object");

try (BufferedReader reader = new BufferedReader(new FileReader("c:\\jsonij.json"))) {

          JSON json = JSON.parse(reader);

 

          // Now we need to parse the JSONObject object and put values back 

          // to our Json object

          for (Field field : jsonObj.getClass().getDeclaredFields()) {

                    try {

                              field.setAccessible(true);

                              field.set(field.getName(), json.get(field.getName()));

                    } catch (IllegalArgumentException | IllegalAccessException e) {

                    }

          }

} catch (FileNotFoundException e) {

} catch (IOException | ParserException e) {

}

 

 

 

看起來JSONiJ需要的代碼多些,性能怎麼樣,我們看下面。

 (二)基准測試

現在我們要來看看性能了,測試硬件配置:Intel Core i5 laptop with 2.50GHz 單通道DDR3 RAM 4G,軟件配置:Windows 7 Ultimate 64-bit SP1

基准測試運行一樣的虛擬機(JVM),在測試之前,每一個類庫都有一個熱身,去限制內存使用的造成的影響,用一個顯式調用垃圾收集器。下面的圖表代表的是序列化和反序列化JSON數據以毫秒級使用50次迭代和10次熱身(warm-up)迭代的平均的時間。

(譯者注:紅色為序列化(Java對象轉JSON),藍色為反序列化(JSON轉Java對象))

上面的圖表顯示,Flexjson序列化小數據時是最快的,而JSON-lib是最慢的。反序列化的時候,Gson最快,JSON-lib還是最慢的。

 下面的圖表代表的是我們的數據在287kb時,序列化和反序列化所花費的平均時間。

這張圖顯示,我們對少量的數據操作時,最快的是Gson ,之後的是 Genson和Flexjson。

 當變成大數據時,結果變得很不一樣。在下面的圖表中,使用的是108Mb的數據,在序列化的時候,Jackson變成了最快的,Flexjson變成第二快。在反序列化的時候,JSON-lib變成了最快的,之前在處理小數據時,它是最慢的,第二快的是Jackson。

 下面的圖表,顯示的是處理更大一點的數據時,我們應該使用Jackson和JSON-lib。

另外一個重要的測試是關於.jar包的大小。這對於移動端的開發很重要,我們從下圖中看到,json-io最小,之後依次是Flexjson和JSONiJ:

(三)結論

在這篇文章中,我們知道了七種方式來實現Java對象和JSON之間的互相轉換。以及哪一個類庫更快,哪一個更慢,在什麼情況下使用等。作為結論, 如果你在你的應用中是想使用小一點的數據量,你應該使用Flexjson或者Gson,如果你需要大的數據量你應該考慮Jackson 和JSON- lib。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved