前面提到URL尾巴支持添加請求參數,具體格式形如「參數A名稱=A參數值&參數B名稱=B參數值」,但是這種格式只能傳遞簡單的鍵值對信息,不能傳遞結構化數據,也沒法傳遞數組形式的參數,於是它不適用於須要輸入複雜參數的場合。爲此人們發明了一種輕量級的數據交換格式JSON,它的數據格式徹底獨立於編程語言,不但可以表達尋常的鍵值對信息,還支持表達數組形式的各種參數,從而知足了複雜參數的傳輸要求。
不過Java的開發包並未提供相應的工具來處理JSON串,爲此咱們須要在工程中添加第三方JSON解析庫,常見的json處理工具備阿里巴巴的FastJson,它的下載頁面是http://repo1.maven.org/maven2/com/alibaba/fastjson/,最新的版本已經迭代到了1.2.56。若想在代碼中使用FastJson的工具,則需先將它的jar包添加到工程的支持庫,右擊Eclipse左邊項目視圖中的工程名稱,在右鍵菜單中依次選擇「Build Path」——「Configure Build Path ...」。在彈出的新窗口中單擊右邊的Libraries選項卡,接着單擊右側的「Add JARs...」按鈕,在另外一個彈窗中找到fastjson-1.2.56.jar,以下圖所示。html
而後單擊OK按鈕,回到前一個彈窗也單擊OK按鈕,完成FastJson的支持庫引入操做。
接下來瀏覽一個購物訂單的JSON串例子,具體內容見下:編程
{ "user_info":{ "name":"思無邪", "address":"桃花島水簾洞123號", "phone":"15960238696" }, "goods_list":[ { "goods_name":"Mate30", "goods_number":1, "goods_price":8888 }, { "goods_name":"格力中央空調", "goods_number":1, "goods_price":58000 }, { "goods_name":"紅蜻蜓皮鞋", "goods_number":3, "goods_price":999 } ] }
從以上json串的內容能夠梳理出它的基本格式定義,詳細說明以下:
一、整個json串由一對花括號包裹,而且內部的每一個結構都以花括號包起來;
二、參數格式相似鍵值對,其中鍵名與鍵值之間以冒號分隔,形如「鍵名:鍵值」;
三、兩個鍵值對之間以逗號分隔;
四、鍵名須要用雙引號括起來,鍵值爲數字的話則無需雙引號,爲字符串的話仍需雙引號;
五、json數組經過方括號表達,方括號內部依次羅列各個元素,具體格式形如「數組的鍵名:[元素1,元素2,元素3]」;
因而可知,JSON串的格式定義很簡潔,層次結構也很清晰。使用FastJson解析json串更是方便,首先調用JSONObject的parseObject方法,獲得某個json串的JSONObject對象,示例代碼以下:json
// 根據json串得到JSONObject對象 JSONObject object = JSONObject.parseObject(json);
接着就能對JSONObject對象開展進一步的操做,主要的處理方法說明以下:
getString:獲取指定鍵名的字符串。
getIntValue:獲取指定鍵名的整型數。
getDoubleValue:獲取指定鍵名的雙精度數。
getBooleanValue:獲取指定鍵名的布爾值。
getJSONObject:獲取指定鍵名的JSONObject對象。
getJSONArray:獲取指定鍵名的JSONArray數組。注意JSONArray類型派生自清單List,意味着能夠把它看成清單同樣讀寫。
put:添加指定的鍵值對信息。
remove:移除指定鍵名的鍵值對。
clear:清空當前的JSONObject對象。
toJSONString:把JSONObject對象轉換爲字符串。數組
針對前述的購物訂單json串,爲了有效地保存解析後的訂單信息,有必要定義幾個相應的實體類。好比要定義一個用戶信息類,該類的定義代碼以下所示:數據結構
//定義一個用戶信息 public class UserInfo { public String name; // 用戶姓名 public String address; // 收貨地址 public String phone; // 聯繫號碼 }
再定義一個商品項信息類,該類的定義代碼以下所示:maven
//定義一項商品信息 public class GoodsItem { public String goods_name; // 商品名稱 public int goods_number; // 商品數量 public double goods_price; // 商品價格 }
最後定義外層的購物訂單信息類,該類的定義代碼以下所示:編程語言
//定義一次購物訂單信息 public class GoodsOrder { // 用戶信息 public UserInfo user_info = new UserInfo(); // 購買的商品清單 public List<GoodsItem> goods_list = new ArrayList<GoodsItem>(); }
定義好了這些實體類,便可將JSONObject對象中的各個數據解析並填入購物訂單對象,完整的json解析代碼示例以下:工具
// 把json字符串解析到對應的實體對象 private static GoodsOrder testParserJson(String json) { // 建立一個購物訂單對象 GoodsOrder order = new GoodsOrder(); // 根據json串得到JSONObject對象 JSONObject object = JSONObject.parseObject(json); // 從JSONObject對象中獲取鍵名爲user_info的用戶信息json對象 JSONObject user_info = object.getJSONObject("user_info"); // 從用戶信息json對象中獲取鍵名爲name的字符串 order.user_info.name = user_info.getString("name"); // 從用戶信息json對象中獲取鍵名爲address的字符串 order.user_info.address = user_info.getString("address"); // 從用戶信息json對象中獲取鍵名爲phone的字符串 order.user_info.phone = user_info.getString("phone"); System.out.println(String.format("用戶信息以下:姓名=%s,地址=%s,手機號=%s", order.user_info.name, order.user_info.address, order.user_info.phone)); // 從JSONObject對象中獲取鍵名爲goods_list的商品信息json數組 JSONArray goods_list = object.getJSONArray("goods_list"); for (int i=0; i<goods_list.size(); i++) { // 遍歷商品信息數組 GoodsItem item = new GoodsItem(); // 建立一項商品對象 // 從json數組獲取下標爲i的商品json對象 JSONObject goods_item = (JSONObject) goods_list.get(i); // 從商品json對象中獲取鍵名爲goods_name的字符串 item.goods_name = goods_item.getString("goods_name"); // 從商品json對象中獲取鍵名爲goods_number的整型數 item.goods_number = goods_item.getIntValue("goods_number"); // 從商品json對象中獲取鍵名爲goods_price的雙精度數 item.goods_price = goods_item.getDoubleValue("goods_price"); System.out.println(String.format("第%d個商品:名稱=%s,數量=%d,價格=%f", i+1, item.goods_name, item.goods_number, item.goods_price)); order.goods_list.add(item); // 往商品清單中添加指定商品對象 } return order; // 返回解析後的購物訂單對象 }
運行上述的解析代碼,觀察到如下的購物訂單日誌,可見成功實現了json串到對象的解析操做:ui
用戶信息以下:姓名=思無邪,地址=桃花島水簾洞123號,手機號=15960238696 第1個商品:名稱=Mate30,數量=1,價格=8888.000000 第2個商品:名稱=格力中央空調,數量=1,價格=58000.000000 第3個商品:名稱=紅蜻蜓皮鞋,數量=3,價格=999.000000
注意到商品訂單json串跟GoodsOrder定義的數據結構一一對應,不論是參數名稱仍是參數類型所有吻合,如此一來就能運用FastJson的自動轉換絕技,整個自動轉換隻有兩次代碼調用:第一次調用JSONObject的parseObject方法,得到json串對應的JSONObject對象;第二次調用JSONObject的toJavaObject方法,依次填寫上一步驟的JSONObject對象,以及待轉換的實體類型如GoodsOrder.class。下面即是將json串自動轉換成實體對象的代碼例子:日誌
// 根據json串得到JSONObject對象 JSONObject object = JSONObject.parseObject(json); // 把JSONObject對象中的信息一一轉成購物訂單信息 GoodsOrder order = (GoodsOrder) JSONObject.toJavaObject(object, GoodsOrder.class);
哇噻,這個自動轉換功能不要太好用喲,實乃開發者的一大福音。反過來,把某個實體對象轉換成對應的json串,也只需短短一行代碼就搞定了,調用JSONObject的toJSONString方法便可,具體轉換代碼示例以下:
// 把購物訂單對象轉換成json字符串 String json = JSONObject.toJSONString(order);
固然,有時候並不須要把整個實體對象都轉換爲json串,而是提取該對象的部分信息再封裝成json串,這樣的話,仍是按照慣例逐步往json串添加鍵值對信息,也就是須要封裝的數據纔要put進JSONObject對象。下面是根據購物訂單對象逐步生成json串的代碼例子:
// 根據購物訂單對象逐步拼接生成json字符串 private static String testGenerateJson(GoodsOrder order) { // 建立一個準備保存購物訂單的JSONObject對象 JSONObject object = new JSONObject(); // 建立一個準備保存用戶信息的JSONObject對象 JSONObject user_info = new JSONObject(); // 往用戶信息json對象中添加鍵名爲name的姓名信息 user_info.put("name", order.user_info.name); // 往用戶信息json對象中添加鍵名爲address的地址信息 user_info.put("address", order.user_info.address); // 往用戶信息json對象中添加鍵名爲phone的號碼信息 user_info.put("phone", order.user_info.phone); // 往購物訂單json對象中添加鍵名爲user_info的用戶信息 object.put("user_info", user_info); // 建立一個準備保存商品項的JSONArray數組 JSONArray goods_list = new JSONArray(); // 遍歷購物訂單裏的各項商品 for (GoodsItem item : order.goods_list) { // 建立一個準備保存商品信息的JSONObject對象 JSONObject goods_item = new JSONObject(); // 往商品信息json對象中添加鍵名爲goods_name的名稱信息 goods_item.put("goods_name", item.goods_name); // 往商品信息json對象中添加鍵名爲goods_number的數量信息 goods_item.put("goods_number", item.goods_number); // 往商品信息json對象中添加鍵名爲goods_price的價格信息 goods_item.put("goods_price", item.goods_price); goods_list.add(item); // 往json數組中添加JSONObject對象 } // 往購物訂單json對象中添加鍵名爲goods_list的商品項信息 object.put("goods_list", goods_list); return object.toJSONString(); // 把JSONObject對象轉換爲json字符串 }
更多Java技術文章參見《Java開發筆記(序)章節目錄》