閱讀573 返回首頁    go 阿裏雲 go 技術社區[雲棲]


處理JSON的Java API :JSON的簡介

處理JSON的各種解析、生成、處理、轉換和查詢的JAVA API

JSON (JavaScript Object Notation)是一種輕量級的、基於文本的、完全獨立於語言的數據交換格式。它非常方便人們和機器的閱讀和書寫。JSON 有兩種結構類型的表現方式對象和數組。對象是名/值對的無序集合。數組是值(value)的有序集合。值的類型可以是字符串(在雙引號中)、數字(整數或浮點數)、邏輯值(true或false)、數組(在方括號中)、對象(在花括號中)、null。

列表1來自 Wikipedia 以JSON表示的一個對象去描述一個人。這個人的姓和名都是字符串類型,一個數值表示了年齡,一個對象表示了這個人的地址,還有一個數組對象表示了電話號碼。

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": 10021
    },
    "phoneNumbers": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567" 
        }
    ] 
}

列表 1. JSON表示對象的一個例子

JSON通常被用在Ajax應用、配置、數據庫和RESTful web services。幾乎所有流行的網站都提供了JSON的數據交換方式在他們的RESTful web services上。

處理JSON

處理JSON的Java API (JSR 353)提供了各種便捷的API,其中包括解析、生成、轉換和使用對象模 型或流來查詢JSON。

對象模型的API在內存中產生一個隨機存取的樹狀結構來代表了JSON數據。這個樹可以被操作和查詢。這種編程模型可以很靈活的處理需要隨機存取完整內容的樹。但是,對象模型通常都沒有流模型效率高,而且需要的存儲空間也比流模型多

流API提供了一種以流來解析和生成JSON的方法。它把解析生成JSON的控製權交給了程序猿。流API提供了一種基於事件的解析器並且允許開發者詢問下一個事件,而不是再一個回調函數中負責事件的處理。它給予了開發者更多的處理JSON的過程控製。應用程序代碼可以處理或拋棄解析器事件,也可以詢問下一個事件(pull the event)。流模型適合於部分不需要的數據的隨機存取的局部處理。同樣的,流API提供了一種通過寫一次事件生成結構良好的JSON流。

對象模型API

對象模型API和文件對象模型(DOM)API在xml中很相似。這是一個高級的API,它為JSON對象和數組結構提供了不可變的對象模型。這些JSON結構通過使用 JsonObjectJsonArray被表示為對象模型。表格1中展示了對象模型API的主要的類和接口。

JsonObject提供了一個Map視圖去存取含有名/值對的無序集合。同樣的,JsonArray提供了一個List去存取含有值的有序序列。

表格 1.對象模型API中主要的類和接口

類和接口 描述
Json 包含產生JSON readers,writers,builders,和他們的工廠對象的靜態方法
JsonGenerator 一次一個值的將JSON數據寫入一個流中。
JsonReader 從流中讀取JSON數據,並且創建一個對象模型在內存中
JsonObjectBuilder
JsonArrayBuilder
在內存中通過向源碼中加入一個值,創建一個對象模型或者數組模型
JsonWriter 從內存中拿出一個對象模型寫入流中
JsonValue
JsonObject
JsonArray
JsonString
JsonNumber
表示JSON數據中的數據類型.

JsonObject,JsonArray,JsonString 和JsonNumber 是JsonValue的子類型。他們是被定義在API中的常量,有null,true,false的JSON值。

對象模型API使用建造者設計模式,從頭創建這些對象模型。應用程序代碼可以使用接口JsonObjectBuilder 來創建模型來代表JSON對象。由此產生的模型是JsonObject。應用程序代碼可以使用接口JsonArrayBuilder來創建模型來代表JSON數組。由此產生的模型JsonArray。

這些對象模型也可以從一個輸入源(例如InputStream或Reader)使用接口JsonReader來創建。同樣的,可以寫出到一個輸出源(例如OutputStream或Writer)使用類JsonWriter。

舉個例子,讓我們使用對象模型API寫個搜索Facebook的公開崗位的code。Facebook的API給我們了搜索結果在列表2中。

1 {
2     "data" : [
3         { "from" : { "name" : "xxx", ... }, "message" : "yyy", ... },
4         { "from" : { "name" : "ppp", ... }, "message" : "qqq", ... },
5         ...
6     ],
7     ...
8 }

列表 2. 搜索Facebook公開崗位的JSON示例

我們可以使用對象模型API取得關於JAVA的名字和他們的崗位。
在列表3中,
第3行創建了JsonReader;
第5行創建了返回結果的JsonObject;
第7行循環每一個結果;
第8-11行取得了公布人的姓名和職位,並且打印它們
注意JsonReader和其他API上的對象可以用於帶有資源的try語法中(這也叫做自動資源管理[ARM]).

 1 URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
 2 try (InputStream is = url.openStream();
 3      JsonReader rdr = Json.createReader(is)) {
 4
 5     JsonObject obj = rdr.readObject();
 6     JsonArray results = obj.getJsonArray("data");
 7     for (JsonObject result : results.getValuesAs(JsonObject.class)) {
 8         System.out.print(result.getJsonObject("from").getString("name"));
 9         System.out.print(": ");
10         System.out.println(result.getString("message", ""));
11         System.out.println("-----------");
12     }
13 }

列表 3. 使用對象模型API處理Facebook的崗位。

流API

流API與XML的流API(StAX)類似,它是由接口JsonParser和JsonGenerator組成。JsonParser 包含使用流模型解析JSON數據的方法JsonGenerator包含輸出JSON數據到一個輸出源的方法。
表格2展示了流API中主要的類和接口

表格 2. 流API中主要的類

類或接口 描述
Json 包含創建JSON解析器,生成器,和工廠對象的靜態方法。
JsonParser 表示一個基於事件的解析器,可以從流中讀取JSON數據。
JsonGenerator 每次一個值將JSON數據寫出到流中

JsonParser提供了先鋒,使用pull 解析對象模型,訪問隻讀的JSON數據。在這個模型中,應用程序代碼在解析器接口中,控製線程和方法調用,來使解析器向前移動或者從當前解析器的狀態獲得JSON數據。

JsonGenerator提供了將JSON數據寫入流的方法。生成器可以在JSON對象中寫入名/值對,在JSON數組中寫入值。

流API是一個低級的API,它被設計用來更效率的處理大量的JSON數據。其他的JSON框架(例如JSON binding) 通過使用API可以繼承(implement)。

讓我們使用流API來做一下剛才使用對象模型API做過的事情。搜索Facebook的關於JAVA的崗位。
在列表4中,
第1-3行創建了一個流的解析器,
第4-5行取得了下一個事件
第6行尋找KEY_NAME這個事件,
第8到11行讀取名字並打印它們,
第14-16行讀取職位並輸出他們。
當使用對象模型API比較相同的工作,流API提供了一種有效的方式存取名字和職位。

 1 URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
 2 try (InputStream is = url.openStream();
 3      JsonParser parser = Json.createParser(is)) {
 4     while (parser.hasNext()) {
 5         Event e = parser.next();
 6         if (e == Event.KEY_NAME) {
 7             switch (parser.getString()) {
 8                 case "name":
 9                     parser.next();
10                    System.out.print(parser.getString());
11                    System.out.print(": ");
12                    break;
13                case "message":
14                    parser.next();
15                    System.out.println(parser.getString());
16                    System.out.println("---------");
17                    break;
18             }
19         }
20     }
21 }

列表 4. 使用流API處理Facebook的崗位信息

結論

處理JSON的Java API提供了如下功能

  • 將輸入流解析為不可變的對象或事件流
  • 將事件流或不可變對象寫入輸出流中
  • 編程操作不可變對象
  • 使用builders編程構建不可變對象

構建數據綁定,轉換,查詢或其他的操作API基礎。JAX-RS 2.0 提供了原始整合為處理JSON的JAVA API。

參見

關於作者

Jitendra Kotamraju,Oracle技術人員的主要成員,是JSON處理規範領導和GlassFish之後的一個關鍵工程師。在領導JSON處理計劃之前,他負責JAX-WS 2.2 的規範和實現

加入會話

加入 FacebookTwitter和 Oracle Java Blog!

最後更新:2017-05-23 17:32:00

  上一篇:go  並發工具類(一)等待多線程完成的CountDownLatch
  下一篇:go  《迷人的8051單片機》----2.3場效應晶體管