JSON詳解
-
什麼是JSON
JSON(JavaScript Object Notation http://www.json .org/json -zh.html ),是一種輕量級的基於文字且獨立於語言的資料交換格式,比XML更輕巧,它是XML資料交換的一個替代方案。它源於ECMAScript程式語言標準-第3版(ECMA-262 3rd Edition - December 1999)的子集,定義了便於表示結構化資料的一套格式規範,JSON規範是符合ECMAScript語法規範,這樣按JSON規範描述出的字串已是 JavaScript的原生程式碼串,這使之能通過eval動態的在JSON串與JavaScript物件之間進行轉換。如果誇大來說,它是另一種理想的但有別於XML資料交換語言。
-
JSON建構於兩種結構
“名稱/值”對的集合(A collection of name/value pairs)。不同的語言中,它被理解為物件(object),紀錄(record),結構(struct),字典(dictionary),雜湊表(hash table),有鍵列表(keyed list),或者關聯陣列 (associative array)。
值的有序列表(An ordered list of values)。在大部分語言中,它被理解為陣列(array)。
這些都是常見的資料結構。事實上大部分現代計算機語言都以某種形式支援它們。這使得一種資料格式在同樣基於這些結構的程式語言之間交換成為可能。
-
JSON語法規則
物件是一個無序的“‘名稱/值’對”集合。一個物件以“{”(左括號)開始,“}”(右括號)結束。每個“名稱”後跟一個“:”(冒號);“‘名稱/值’ 對”之間使用“,”(逗號)分隔。
陣列是值(value)的有序集合。一個陣列以“[”(左中括號)開始,“]”(右中括號)結束。值之間使用“,”(逗號)分隔。
值(value)可以是雙引號括起來的字串(string)、數值(number)、true、false、 null、物件(object)或者陣列(array)。這些結構可以巢狀。
字串(string)是由雙引號包圍的任意數量Unicode字元的集合,使用反斜線轉義。一個字元(character)即一個單獨的字串(character string)。與C或者Java的字串非常相似。
-
快速瀏覽JSON與XML表現形式
假如有一個employee物件,它有“姓、名、員工編號、頭銜”等資訊,先看看JSON是如何來描述它的:
- {
- employee :
- {
- firstName: "John",
- lastName : "Doe",
- employeeNumber : 123,
- title : "Accountant"
- }
- }
再來看看XML是如何表示的,請看:
- <employee>
- <firstName>John</firstName>
- <lastName>Doe</lastName>
- <employeeNumber>123</employeeNumber>
- <title>Accountant</title>
- </employee>
從上面描述看,JSON表示法不正是JavaScript中物件描述的一種方式麼?正確,這正是JavaScript中的物件構造的原生程式碼。既然是原生程式碼,我們把它轉換成JavaScript中的物件,這樣我們操作物件就比操作字串方便多了。
把JSON字串轉換成JavaScript物件:
- <script type="text/javascript">
- //使用script本身的函式eval將JSON串解析成物件
- var e = eval(
- '({' +
- 'employee : ' +
- '{' +
- 'firstName: "John",' +
- 'lastName : "Doe",' +
- 'employeeNumber : 123,' +
- 'title : "Accountant"' +
- '}' +
- '})'
- );
- //現在我們可以使用e這個物件了,還可以以點的訪問形式來訪問物件的屬性
- alert(e.employee.firstName);
- alert(e.employee.lastName);
- alert(e.employee.employeeNumber);
- alert(e.employee.title);
- </script>
看完上述後我們來對比它們。
-
XML與JSON比對
經過一番快速瀏覽後如何?感覺到沒有JSON的設計上比XML更輕巧簡潔?先前就說過了,正是它符合JavaScript語言物件本身特點,這使得如果伺服器傳來的文字是符合JavaScript語法定義語句的字串,那豈不是一條eval方法就能解析了?的確如此~
從上面兩者的表示來看,JSON表示法在語法上要比XML要簡潔的多,由於不需要使用關閉標籤來呼應開始標籤,因此許多多餘的資訊不再出現了,相對XML而言基本上不存在資料冗餘,這在傳輸與響應速度上大在提高了。
另外,JSON不只是在表現形式上有如此的優勢,最重要的是可以丟棄以前弄得我們暈頭轉向的DOM解析了(客戶端的JavaScript的XML DOM解析,伺服器端的DOM、SAX、Dom4j、Jdom等)。JSON與XML相比對JavaScript有著更好的通用性,一段JSON格式資料經過JavaScript一個簡單的方法(eval)即可轉換成 JavaScript物件供程式呼叫,轉換方法是瀏覽器的JavaScript內部定義好的無需再手工編寫。而一段XML格式的資料需要呼叫瀏覽器內部的 XML解析器工具進行解析後才可以使用。而對於不同核心的瀏覽器(如IE、Netscape等)XML解析的方法是有差別的,因此需要針對不同瀏覽器核心做不同的方法封裝,從而給客戶端開發帶來一定的複雜度。相比之下JSON被瀏覽器解析的速度更快。在伺服器端不同的語言也有不同的JSON解析器,可以很方便的解析客戶端傳過來的字串,而不像為了讀取XML還是藉助於這樣或那樣的API工具。
-
JSON優缺點
優點:
乍看上去,使用JSON的資料分隔符的優點可能並不那麼明顯,但存在一個根本性的緣由:它們簡化了資料訪問。使用這些資料分隔符時, JavaScript引擎對資料結構(如字串、陣列、物件)的內部表示恰好與這些符號相同。
JSON的另一個優點是它的非冗長性。在XML中,開啟和關閉標記是必需的,這樣才能滿足標記的依從性;而在JSON中,所有這些要求只需通過一個簡單的括號即可滿足。在包含有數以百計欄位的資料交換中,傳統的XML標記將會延長資料交換時間
此外,JSON受到了擅長不同程式語言的開發人員的青睞。這是因為無論在Haskell中或 Lisp中,還是在更為主流的C#和Java中,開發都可以方便地生成JSON。
不足:
和許多好東西都具有兩面性一樣,JSON的非冗長性也不例外,為此JSON丟失了XML具有的一些特性。名稱空間允許不同上下文中的相同的資訊段彼此混合,然而,顯然在JSON中已經找不到了名稱空間。JSON與XML的另一個差別是屬性的差異,由於JSON採用冒號賦值,這將導致當XML轉化為 JSON時,在識別符號(XML CDATA)與實際屬性值之間很難區分誰應該被當作文字考慮。
另外,JSON片段的建立和驗證過程比一般的XML稍顯複雜。從這一點來看,XML在開發工具方面領先於JSON。
JSON實踐
預備知識
-
動態指令碼函式eval ()
在進一步學習之前,我們有必要講解一下eval方法的用法,懂的同學可以跳過。
eval() 函式可計算某個字串,並執行其中的的 JavaScript 程式碼。它接收一個引數s,如果s不是字串,則直接返回s。否則執行s語句。如果s語句執行結果是一個值,則直接返回此值,否則返回undefined。
另外,該方法只接受原始字串作為引數,如果 string 引數不是原始字串,那麼該方法將不作任何改變地返回。因此請不要為 eval() 函式傳遞 String 物件來作為引數:
- var str = new String("alert('msg')");
- //請不要傳遞String物件,否則直接返回string物件了
- alert(eval(str)==str);//true
- //應該傳遞原始string字串,這樣才看作JavaScript指令碼並執行
- eval("alert('msg')");//msg
最後,需要特別注意的是物件宣告語法“{}”並不能返回一個值,需要用括號括起來才會返回值(括號裡的指令碼是表示式,有返回值,而不是無返回值的邏輯式,因為大括號裡的指令碼又可能是表示式,又可能是普通的邏輯表達,所以用小括號括起來後明確的說明是值表示式):
- var str="{}";//花括號內沒屬性時
- alert(eval('(' + str + ')'));//彈出:[object Object]
- alert(eval(str));//彈出:undefined
- str="{name:'jzj'}";//花括號內有一個屬性
- alert(typeof eval('(' + str + ')'));//彈出:object,以物件方式返回
- alert(eval(str));//彈出:jzj
- alert(eval('(' + str + ')').name);//彈出:jzj
- alert(eval(str).name);//彈出:undefined
- str="{name:'jzj',age:30}";//花括號內有多個屬性時
- alert(eval('(' + str + ')'));//
- alert(eval('(' + str + ')').name);//jzj
- alert(eval('(' + str + ')').age);//30
- //alert(eval(str));//執行時會出錯,多個屬性時不用小括號執行出錯
可以看到,對於物件宣告語句來說,僅僅是執行,並不能返回值 。為了返回常用的“{}”這樣的物件宣告語句,必須用括號括住,以將其轉換為表示式,才能返回其值 。這也是使用JSON來進行Ajax開發的基本原理之一。
現來說說本節的重點,就是在應用eval時,動態指令碼所生成的變數都區域性的,但很多時候我們可能在呼叫eval函式的外面使用生成的變數,eval不可能在全域性空間內執行,這就給開發帶來了不少問題,這該如何作?請看繼續往下看吧。
我們先來證實一下eval產生的變數是區域性性的,在呼叫eval函式外是不能訪問到此變數的。
- var str='全域性';//定義一個全域性變數
- function test(){
- eval('var str="區域性"');
- alert(str);//區域性
- }
- test();
- alert(str); //彈出:全域性
另外,eval生成的函式也是區域性的,它只能在生成它的函式內使用,出函式域就不能呼叫的到。
解決辦法:
- function gloablEval(code){
- if(window.attachEvent && !window.opera){
- //ie
- execScript(code);
- }else{
- //not ie window物件不能省,否則生成的變數在執行的函式外不可見
- window.eval(code);
- alert(str);//區域性
- //eval(code);
- //alert(str);//區域性
- }
- }
- var str='全域性';//定義一個全域性變數
- gloablEval('var str="區域性"');
- alert(str); //彈出:區域性,這裡用區域性的履蓋了全域性變數的值
現解釋一下:
1、對於IE瀏覽器,預設已經提供了這樣的函式:execScript,用於在全域性空間執行程式碼。
2、對於Firefox瀏覽器,直接呼叫eval函式,則在呼叫者的空間執行;如果呼叫window.eval則在全域性空間執行。
-
JavaScript中的JSON
我們知道,可以使用eval()方法呼叫JavaScript的編譯器把JSON文字轉變成物件。因為JSON是JavaScript的一個確切的子集,編譯器可以正確地解析JSON文字,然後生成一個物件結構。
- var myObject = eval('(' + myJSONtext + ')');
eval函式非常快速。它可以編譯執行任何JavaScript程式,因此產生了安全性問題。當使用可信任與完善的原始碼時才可以使用eval函式。這樣可以更安全的使用JSON解析器。使用XMLHttpRequest的web應用,頁面之間的通訊只允許同源,因此是可以信任的。但這卻不是完善的。如果伺服器沒有嚴謹的JSON編碼,或者沒有嚴格的輸入驗證,那麼可能傳送包括危險指令碼的無效JSON文字。eval函式將執行惡意的指令碼。
如果關心安全的話,使用JSON解析器可以防止此類事件。JSON解析器只能辨識JSON文字,拒絕所有指令碼,因此它比較安全,JSON官方網站提供的一個開源的JSON解析器和字串轉換器(http://www.json.org/json.js )。
- var myObject = myJSONtext.parseJSON();
而JSON的字串轉換器(stringifier)則作相反的工作,它將JavaScript資料結構轉換為JSON文字。JSON是不支援迴圈資料結構的,所以注意不能把迴圈的結構交給字串轉換器。
- var myJSONText = myObject.toJSONString();
-
Java中的JSON
Java中的JSON直譯器官方提供了好幾種,我們這裡使用的是org.json 包,關於如何使用,請參見另一篇《JSON之org.json包測試》 ,它是基於官方包提供的測試改寫而來的。
開始實戰
本例項實現了客戶端與伺服器端通過JSON進行引數的傳遞與接收,而不是通過原來的XML方式進行通訊。頁面採用了Prototype的Ajax方式進行非同步通訊,並採用了官方json.js 進行物件與JSON串的靈活互轉。伺服器端採用了官方提供org.json 包進行JSON串與Java物件的互轉。具體的細節請看程式碼註釋。
客戶端實現:
- <html>
- <head>
- <title> JSON Address Book </title>
- </head>
- <body>
- <div style="text-align:left" id="addressBookResults"></div>
- <script type="text/javascript" src="prototype-1.4.0.js"></script>
- <script type="text/javascript" src="json.js"></script>
- <script type="text/javascript">
- //address物件
- function address(city,street,zip){
- this.city = city;//城市
- this.street = street;//街道
- this.zip = zip;//郵編
- }
- //addressbook物件
- function addressbook(city,street,zip,name,tel1,tel2){
- //addressbook物件中含有address物件屬性
- this.address = new address(city,street,zip);
- //人的名字屬性
- this.name = name;
- //人的電話號碼屬性,且有兩個電話號碼
- this.phoneNumbers = [tel1,tel2];
- }
- //建立兩個addressbook物件例項,這些信在實際的專案中是由使用者通過頁面輸入的
- var addressbookObj1 = new addressbook("Seattle, WA","P.O BOX 54534",
- 42452,"Ann Michaels",
- "561-832-3180","531-133-9098");
- var addressbookObj2 = new addressbook("Miami, FL","53 Mullholand Drive",
- 72452,"Betty Carter",
- "541-322-1723","546-338-1100");
- //建立要傳遞給後臺的引數物件
- var paramObj={};
- //因為有多個(這裡是兩個),我們用陣列的形式
- paramObj.addressbook=new Array(addressbookObj1,addressbookObj2);
- //通過物件例項的toJSONString方法,JavaScript物件轉JSON串
- var param = paramObj.toJSONString();
- //alert(param);
- // 定義 service URL
- var url = '/json_addressbook/addrbk?timeStamp='+new Date();
- // 通過原型建立AJAX請求的WEB服務, 響應後, 回撥 showResponse 方式
- new Ajax.Request( url, { method: 'post', parameters:"jsonStr="+param,
- onComplete: callBack });
- // 回撥方法,接收伺服器返回過來的JSON串,
- //並用eval函式或String物件例項parseJSON轉換成JavaScript物件
- function callBack(originalRequest) {
- // 獲取伺服器返回的JSON原始串
- var jsonRaw = originalRequest.responseText;
- //原始串轉換成JavaScript物件
- //var jsonRawObj = eval("(" + jsonRaw + ")");用此種方式也行
- var jsonRawObj = jsonRaw.parseJSON();
- //從json原始物件中提取HTML格式串
- var jsonHtmlStr = jsonRawObj.jsonHtmlStr;
- //提取AddreeBook的JSON串
- var jsonCode = jsonRawObj.jsonCode;
- // 通過eval動態的把JSON響應串構造成JavaScript物件
- //var jsonContent = jsonCode.parseJSON();用此種方式也行
- jsonContent = eval("(" + jsonCode + ")");
- // 從伺服器獲取的JSON格式串後,顯示資料到頁面
- finalResponse = "<b>伺服器返回的JSON串如下: </b><br/><br>";
- finalResponse += jsonHtmlStr+"<br/>";
- finalResponse += "<br><b>從JSON物件提取資訊如下: </b><br/><br>";
- // 根據地址薄長度迴圈.
- for (i = 0; i < jsonContent.addressbook.length; i++) {
- finalResponse += "<hr/>";
- finalResponse += "<i>Name:</i> " + jsonContent.addressbook[i].name + "<br/>";
- finalResponse += "<i>Address:</i> " + jsonContent.addressbook[i].address.street
- + " -- " +
- jsonContent.addressbook[i].address.city[0] + "," +
- jsonContent.addressbook[i].address.zip + ".<br/>";
- finalResponse += "<i>Telephone numbers:</i> "
- + jsonContent.addressbook[i].phoneNumbers[0] + " & " +
- jsonContent.addressbook[i].phoneNumbers[1] + ".";
- }
- // 把結果置換到結果區域並顯示
- document.getElementById("addressBookResults").innerHTML = finalResponse;
- }
- </script>
- </body>
- </html>
頁面展示結果:
JSON Address Book
伺服器返回的JSON串如下:
{"addressbook": [ { "address": { "city": [ "Seattle, WA", "changsha" ], "street": ["P.O BOX 54534"], "zip": [42452] }, "name": "Ann Michaels", "phoneNumbers": [ "561-832-3180", "531-133-9098" ] }, { "address": { "city": [ "Miami, FL", "changsha" ], "street": ["53 Mullholand Drive"], "zip": [72452] }, "name": "Betty Carter", "phoneNumbers": [ "541-322-1723", "546-338-1100" ] } ]} 從JSON物件提取資訊如下: Name: Ann Michaels Address: P.O BOX 54534 -- Seattle, WA,42452. Telephone numbers: 561-832-3180 & 531-133-9098. Name: Betty Carter Address: 53 Mullholand Drive -- Miami, FL,72452. Telephone numbers: 541-322-1723 & 546-338-1100. |
伺服器端實現:
- package orgjson;
- import java.io.IOException;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.SortedMap;
- import java.util.TreeMap;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import bean.Address;
- /**
- * 使用 org.josn 包進行解析操作
- * (C) 2009-9-1, jzjleo
- */
- public class AddressServlet extends HttpServlet {
- private static final long serialVersionUID = -1762985503942785440L;
- protected void service(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // 建立addressbook資料結構
- SortedMap addressBook = new TreeMap();
- // 建立新的address實體並放置到Map中
- Address annMichaels = new Address("P.O BOX 54534", "Seattle, WA", 42452,
- "561-832-3180", "531-133-9098");
- addressBook.put("Ann Michaels", annMichaels);
- Address bettyCarter = new Address("53 Mullholand Drive", "Miami, FL", 72452,
- "541-322-1723", "546-338-1100");
- addressBook.put("Betty Carter", bettyCarter);
- try {
- // 準備轉換通訊簿對映到JSON陣列
- // 陣列用於放置多個地址條目
- JSONArray jsonAddressBook = new JSONArray();
- // 迭代過濾地址簿條目
- for (Iterator iter = addressBook.entrySet().iterator(); iter.hasNext();) {
- // 找當前迭代項
- Map.Entry entry = (Map.Entry) iter.next();
- String key = (String) entry.getKey();
- Address addressValue = (Address) entry.getValue();
- // 以鍵值對的形式存入條目並分配給"name"
- JSONObject jsonResult = new JSONObject();
- jsonResult.put("name", key);
- // 獲取和創造相應的地址結構,繫結到新Key
- // 追加地址條目到JSON格式結果
- String streetText = addressValue.getStreet();
- String cityText = addressValue.getCity();
- int zipText = addressValue.getZip();
- //--注:Bean可以直接轉換成JSON串,下面可以採用 new JSONObject(addressValue)
- //形式來自動轉換成JSON串
- JSONObject jsonAddrObj = new JSONObject();
- //以陣列的形式存放,street為存放陣列的變數名即Key,如果key不存在,則新建,如果存在,
- //則在原來陣列後追加
- //jsonAddress.append("street", streetText);
- //上句等價於下面語句
- jsonAddrObj.put("street", new JSONArray().put(streetText));
- jsonAddrObj.append("city", cityText);
- jsonAddrObj.append("city", "changsha");//追加
- //上兩句等價於如下語句
- //jsonAddrObj.put("city", new JSONArray().put(cityText).put("changsha"));
- jsonAddrObj.append("zip", new Integer(zipText));
- jsonResult.put("address", jsonAddrObj);
- // 獲取和結構,建立相應的電話到新的Key
- // 追加在電話條目到JSON格式的結果裡
- String telText = addressValue.getTel();
- String telTwoText = addressValue.getTelTwo();
- JSONArray jsonTelephones = new JSONArray();
- jsonTelephones.put(telText);
- jsonTelephones.put(telTwoText);
- jsonResult.put("phoneNumbers", jsonTelephones);
- // 把JSON地址條目放置到全域性的JSON地址薄陣列裡
- jsonAddressBook.put(jsonResult);
- } // 結束迴圈地址薄
- // 賦值JSON地址薄到結果字元變數
- JSONObject resultJsonObj = new JSONObject().put("addressbook",
- jsonAddressBook);
- //格式化輸出到頁面上的JSON串
- String jsonHtmlStr = resultJsonObj.toString(4).replaceAll(" ", " ")
- .replaceAll("\n", "<br>");
- JSONObject jsonObj = new JSONObject().put("jsonHtmlStr", jsonHtmlStr).put(
- "jsonCode", resultJsonObj.toString());
- // 返回JSON串
- resp.getOutputStream().write(jsonObj.toString().getBytes());
- System.out.println(resultJsonObj.toString(4));
- //System.out.println(jsonObj.toString(4));
- System.out.println("-----------------------------------------------");
- readJSONString(req);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 從客戶端讀取JSON串
- * @param req
- */
- public void readJSONString(HttpServletRequest req) {
- System.out.println("接收到客戶端的JSON資訊如下:");
- JSONObject clientJSONObj;
- try {
- clientJSONObj = new JSONObject(req.getParameter("jsonStr"));
- System.out.println(clientJSONObj.toString(4));
- JSONArray addressbookArray = clientJSONObj.getJSONArray("addressbook");
- for (int i = 0; i < addressbookArray.length(); i++) {
- System.out.println("The" + " " + (i + 1) + " addressbook msg:");
- JSONObject addressbookJSONObj = addressbookArray.getJSONObject(i);
- JSONObject addressJSONObj = addressbookJSONObj.getJSONObject("address");
- System.out.println("address-------");
- System.out.println(" " + addressJSONObj.getString("city"));
- System.out.println(" " + addressJSONObj.getString("street"));
- System.out.println(" " + addressJSONObj.getString("zip"));
- System.out.println("name----------");
- System.out.println(" " + addressbookJSONObj.getString("name"));
- System.out.println("phoneNumbers--");
- JSONArray phoneNumbersArr = addressbookJSONObj
- .getJSONArray("phoneNumbers");
- System.out.println(" " + phoneNumbersArr.getString(0));
- System.out.println(" " + phoneNumbersArr.getString(1));
- System.out.println();
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- }
伺服器後臺列印:
{"addressbook": [ { "address": { "city": [ "Seattle, WA", "changsha" ], "street": ["P.O BOX 54534"], "zip": [42452] }, "name": "Ann Michaels", "phoneNumbers": [ "561-832-3180", "531-133-9098" ] }, { "address": { "city": [ "Miami, FL", "changsha" ], "street": ["53 Mullholand Drive"], "zip": [72452] }, "name": "Betty Carter", "phoneNumbers": [ "541-322-1723", "546-338-1100" ] } ]} ----------------------------------------------- 接收到客戶端的JSON資訊如下: {"addressbook": [ { "address": { "city": "Seattle, WA", "street": "P.O BOX 54534", "zip": 42452 }, "name": "Ann Michaels", "phoneNumbers": [ "561-832-3180", "531-133-9098" ] }, { "address": { "city": "Miami, FL", "street": "53 Mullholand Drive", "zip": 72452 }, "name": "Betty Carter", "phoneNumbers": [ "541-322-1723", "546-338-1100" ] } ]} The 1 addressbook msg: address------- Seattle, WA P.O BOX 54534 42452 name---------- Ann Michaels phoneNumbers-- 561-832-3180 531-133-9098 The 2 addressbook msg: address------- Miami, FL 53 Mullholand Drive 72452 name---------- Betty Carter phoneNumbers-- 541-322-1723 546-338-1100 |
相關文章
- package.json 詳解PackageJSON
- package.json詳解PackageJSON
- JSON.parse 和 JSON.stringify 詳解JSON
- JSON基礎使用詳解JSON
- JSON Web Token 使用詳解JSONWeb
- 標準庫~JSON物件詳解JSON物件
- composer.json 檔案引數詳解JSON
- 詳解JSON和JSONP劫持檢測程式碼以及解決方法JSON
- 『動善時』JMeter基礎 — 30、JMeter中JSON斷言詳解JMeterJSON
- js中eval詳解,用Js的eval解析JSON中的注意點JSON
- 『動善時』JMeter基礎 — 35、JMeter介面關聯【JSON提取器】詳解JMeterJSON
- SpringBoot 預設json解析器詳解和欄位序列化自定義Spring BootJSON
- 前端介面神器之 Json Server 詳細指南前端JSONServer
- 詳解電子表格中的json資料:序列化與反序列化JSON
- 探索多種資料格式:JSON、YAML、XML、CSV等資料格式詳解與比較JSONYAMLXML
- Go JSON編碼與解碼?GoJSON
- JSON.parse()出錯解決JSON
- 蝦皮商品詳情介面返回資料的json格式JSON
- http協議/cookie詳解/session詳解HTTP協議CookieSession
- 解決:npm install ERR! Unexpected end of JSON inputNPMJSON
- ClassNotFoundException: org.json.JSONObject解決辦法ExceptionJSONObject
- 結合實踐解讀 package.jsonPackageJSON
- Hive解析Json陣列超全講解HiveJSON陣列
- Java註解最全詳解(超級詳細)Java
- Java註解詳解Java
- Lombok 註解詳解Lombok
- @FeignClient註解詳解client
- Java 註解詳解Java
- ECharts 詳解Echarts
- Dialogment詳解
- hibernate詳解
- 詳解bind
- 詳解GOPATHGo
- nginx 詳解Nginx
- HTTP 詳解HTTP
- StreamingContext詳解GCContext
- JavaScript this詳解JavaScript
- promise詳解Promise