前面提到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,如下圖所示。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csEjUuJGa41mYwJ0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4gzM3UjNxEjM1AjNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
然後單擊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串的内容可以梳理出它的基本格式定義,詳細說明如下:
1、整個json串由一對花括号包裹,并且内部的每個結構都以花括号包起來;
2、參數格式類似鍵值對,其中鍵名與鍵值之間以冒号分隔,形如“鍵名:鍵值”;
3、兩個鍵值對之間以逗号分隔;
4、鍵名需要用雙引号括起來,鍵值為數字的話則無需雙引号,為字元串的話仍需雙引号;
5、json數組通過方括号表達,方括号内部依次羅列各個元素,具體格式形如“數組的鍵名:[元素1,元素2,元素3]”;
由此可見,JSON串的格式定義很簡潔,層次結構也很清晰。使用FastJson解析json串更是友善,首先調用JSONObject的parseObject方法,得到某個json串的JSONObject對象,示例代碼如下:
// 根據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; // 聯系号碼
}
再定義一個商品項資訊類,該類的定義代碼如下所示:
//定義一項商品資訊
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串到對象的解析操作:
使用者資訊如下:姓名=思無邪,位址=桃花島水簾洞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開發筆記(序)章節目錄》