Java開發筆記(一百零八)JSON串的定義和解析

前面提到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開發筆記(序)章節目錄

相關文章
相關標籤/搜索