JSON的序列化與反序列化及其在前后臺交互中的應(yīng)用

1朗涩、什么是JSON
  JSON是JavaScript Object Notation的縮寫取视,它是一種數(shù)據(jù)交換格式鬼雀。

在JSON出現(xiàn)之前顷窒,大家一直用XML來傳遞數(shù)據(jù)。因為XML是一種純文本格式源哩,所以它適合在網(wǎng)絡(luò)上交換數(shù)據(jù)鞋吉。XML本身不算復(fù)雜,但是励烦,加上DTD谓着、XSD、XPath坛掠、XSLT等一大堆復(fù)雜的規(guī)范以后赊锚,任何正常的軟件開發(fā)人員碰到XML都會感覺頭大了,最后大家發(fā)現(xiàn)屉栓,即使你努力鉆研幾個月舷蒲,也未必搞得清楚XML的規(guī)范。

終于友多,在2002年的一天牲平,道格拉斯·克羅克福特(Douglas Crockford)同學(xué)為了拯救深陷水深火熱同時又被某幾個巨型軟件企業(yè)長期愚弄的軟件工程師惫周,發(fā)明了JSON這種超輕量級的數(shù)據(jù)交換格式睡汹。

道格拉斯同學(xué)長期擔(dān)任雅虎的高級架構(gòu)師膘壶,自然鐘情于JavaScript侦鹏。他設(shè)計的JSON實際上是JavaScript的一個子集疙剑。在JSON中荷并,一共就這么幾種數(shù)據(jù)類型:

 - number:和JavaScript的number完全一致辈末;<br>
 - boolean:就是JavaScript的true或false瓶蝴;
 - string:就是JavaScript的string酬土;
 - null:就是JavaScript的null荆忍;
 - array:就是JavaScript的Array表示方式——[];
 - object:就是JavaScript的{...}表示方式撤缴。

以及上面的任意組合刹枉。

并且,JSON還定死了字符集必須是UTF-8屈呕,表示多語言就沒有問題了微宝。為了統(tǒng)一解析,JSON的字符串規(guī)定必須用雙引號”“虎眨,Object的鍵也必須用雙引號”“蟋软。

由于JSON非常簡單镶摘,很快就風(fēng)靡Web世界,并且成為ECMA標(biāo)準(zhǔn)岳守。幾乎所有編程語言都有解析JSON的庫凄敢,而在JavaScript中,我們可以直接使用JSON湿痢,因為JavaScript內(nèi)置了JSON的解析涝缝。

把任何JavaScript對象變成JSON,就是把這個對象序列化成一個JSON格式的字符串譬重,這樣才能夠通過網(wǎng)絡(luò)傳遞給其他計算機拒逮。如果我們收到一個JSON格式的字符串,只需要把它反序列化成一個JavaScript對象臀规,就可以在JavaScript中直接使用這個對象了滩援。
2、JSON序列化
  讓我們先把小明這個對象序列化成JSON格式的字符串:

var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};

JSON.stringify(xiaoming);
在chrome瀏覽器的console中運行上面代碼塔嬉,輸出結(jié)果如下:

"{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}"

要輸出得好看一些玩徊,可以加上參數(shù),按縮進輸出:

JSON.stringify(xiaoming, null, '  ');
"{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}"

第二個參數(shù)用于控制如何篩選對象的鍵值谨究,如果我們只想輸出指定的屬性佣赖,可以傳入Array:

JSON.stringify(xiaoming, ['name', 'skills'], '  ');
"{
  "name": "小明",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}"

還可以傳入一個函數(shù),這樣對象的每個鍵值對都會被函數(shù)先處理:

function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}
JSON.stringify(xiaoming, convert, '  ');

結(jié)果:

"{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" MIDDLE SCHOOL",
  "skills": [
    "JAVASCRIPT",
    "JAVA",
    "PYTHON",
    "LISP"
  ]
}"

如果我們還想要精確控制如何序列化小明记盒,可以給xiaoming定義一個toJSON()的方法,直接返回JSON應(yīng)該序列化的數(shù)據(jù):

var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return {             // 只輸出name和age外傅,并且改變了key:
            'Name': this.name,
            'Age': this.age
        };
    }
};
JSON.stringify(xiaoming);   // '{"Name":"小明","Age":14}'

3纪吮、JSON反序列化
拿到一個JSON格式的字符串,我們直接用JSON.parse()把它變成一個JavaScript對象:

JSON.parse('[1,2,3,true]');         // Array [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}');   // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45

//還可以接收一個函數(shù)萎胰,用來轉(zhuǎn)換解析出的屬性:

JSON.parse('{"name":"小明","age":14}', function (key, value) {
    // 把number * 2:
    if (key === 'name') {
        return value + '同學(xué)';
    }
    return value;
});     // Object {name: '小明同學(xué)', age: 14}

4碾盟、JSON對象與JSON字符串
在數(shù)據(jù)傳輸流程中,json是以文本技竟,即字符串的形式傳遞的冰肴,而JS操作的是JSON對象,所以榔组,JSON對象和JSON字符串之間的相互轉(zhuǎn)換是關(guān)鍵熙尉。

JSON對象是直接可以使用JQuery操作的格式,和js中的對象一樣搓扯,可以用對象(類名)點出屬性(方法)检痰。JSON字符串僅僅只是一個字符串,一個整體锨推,不截取的話沒辦法取出其中存儲的數(shù)據(jù)铅歼,不能直接使用公壤,除非你只想alert()它。
JSON字符串:

var str1 = '{ "name": "haorooms", "sex": "man" }';

JSON對象:

var str2 = { "name": "haorooms", "sex": "man" };

讀取JSON對象的屬性值:

var str2 = { "name": "haorooms", "sex": "man" };
alert(str2.name);
//彈出” haorooms”
//對于復(fù)雜一點的JSON對象
var str={"GetUserPostByIdResult":{"Age":"33","ID":"2server","Name":"haorooms"}};
alert(str.GetUserPostByIdResult.Name); //彈出haorooms

對于JSON字符串椎椰,如果想像上面那樣自如的讀取其屬性厦幅,必須運用下面的方法將JSON字符串領(lǐng)先轉(zhuǎn)化為JSON對象(這一點在ajax返回的時候,經(jīng)常遇到慨飘!):

var str = '{ "name": "haorooms", "sex": "man" }';
//方法1
var obj1 = eval('(' + str + ')');   //Object {name: "haorooms", sex: "man"}
//方法2
var obj2 = JSON.parse(str);     //Object {name: "haorooms", sex: "man"}

5确憨、JSON實現(xiàn)后臺與前端的交互
作為后臺人員,與數(shù)據(jù)庫交互套媚、處理業(yè)務(wù)邏輯已經(jīng)駕輕就熟缚态,但與前端合作就顯得不是那么熟練了。舉一個例子堤瘤,一個用戶列表玫芦,我們從數(shù)據(jù)庫取出來是一個List<User>,但它在前端顯示就是一個很炫酷的用戶列表本辐,我們后臺人員是需要把數(shù)據(jù)以表格樣式呈現(xiàn)然后讓前端人員去加樣式呢桥帆,還是前端做好樣式留出接口由后臺人員給出數(shù)據(jù)呢?

剛剛接觸網(wǎng)站開發(fā)可能都會出現(xiàn)類似的問題慎皱,我們是多希望前端和后臺的工作分的清清楚楚袄铣妗茫多!其實不用想那么復(fù)雜祈匙,JSON就可以幫我們!后臺只需告訴前端天揖,請求某一個URL地址就可以得到用戶數(shù)據(jù)的JSON格式的數(shù)據(jù)夺欲,前端在需要的時候自己去請求就好,剩下的工作就由前端做就好了今膊,清楚干凈些阅!
代碼實例:

 /**
     * 測試獲取所有用戶列表 
     * @param request 
     * @return String 
     * @throws IOException  
     */  
    @RequestMapping("/getAllUserTest")  
    public String getAllUserTest(HttpServletRequest request, HttpServletResponse response) throws IOException {  
        //從數(shù)據(jù)庫中取出所有用戶信息,返回值為一個User對象集合斑唬,每個User對象包含username與age兩個參數(shù)  
        List<User> findAll = userService.findAll();  
        //創(chuàng)建JSONArray實例  
        JSONArray jsonArray = new JSONArray();  
        //for each循環(huán)取出每個User對象  
        for(User user: findAll) {  
            //JSONObject是一個{}包裹起來的一個對象(Object)市埋,  
            //JSONArray則是[]包裹起來的一個數(shù)組(Array)  
            //此處為對象,所以用得到JSONObject  
             JSONObject jo = new JSONObject();  
             jo.put("username", user.getUsername());  
             jo.put("age", user.getAge());  
             jsonArray.add(jo);  
        }  
        try {  
             //后臺輸出測試  
             System.out.println(jsonArray.toString());  
             //設(shè)置字符集  
             response.setCharacterEncoding("UTF-8");  
             //頁面輸出  
             response.getWriter().println("JSON輸出形式:");  
             response.getWriter().write(jsonArray.toString());  

         } catch (IOException e) {  
             e.printStackTrace();  
         }  
         return null;  
    }  

那么前端請求相應(yīng)的URL就可以得到所有的用戶信息了恕刘!效果如下:


20151206212911695.png

前臺的數(shù)據(jù)如何通過JSON這種數(shù)據(jù)交換格式傳入后臺缤谎?

(1)將要傳入后臺的數(shù)據(jù)組裝成JSON格式的字符串

var data = [{'name':'jim' , 'age':20} , {'name':'king' , 'age':26},{'name':'jge' , 'age':30}];
var jsonString = JSON.stringify(data);

(2)使用jQuery的ajax請求向后臺傳數(shù)據(jù)

$.ajax({
    type: "post",
    url: url,
    dataType : 'json',
    data : {'mydata':jsonString},
    success: function(data,textStatus){
        alert("操作成功");
    },
    error: function(xhr,status,errMsg){
        alert("操作失敗!");
    }
});

(3)后臺接收數(shù)據(jù)并解析

String jsonString = ServletActionContext.getRequest().getParameter("mydata");
JSONArray jsonArray = JSONArray.fromObject(jsonString);
for(int i = 0;i < jsonArray.length(); i++) {
    JSONObject jsonObj = jsonArray.getJSONObject(i);
    jsonObj.getInt("name");
    jsonObj.getString("age");
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市褐着,隨后出現(xiàn)的幾起案子弓千,更是在濱河造成了極大的恐慌,老刑警劉巖献起,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洋访,死亡現(xiàn)場離奇詭異镣陕,居然都是意外死亡,警方通過查閱死者的電腦和手機姻政,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門呆抑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汁展,你說我怎么就攤上這事鹊碍。” “怎么了食绿?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵侈咕,是天一觀的道長。 經(jīng)常有香客問我器紧,道長耀销,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任铲汪,我火速辦了婚禮熊尉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掌腰。我一直安慰自己狰住,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布齿梁。 她就那樣靜靜地躺著催植,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勺择。 梳的紋絲不亂的頭發(fā)上查邢,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音酵幕,去河邊找鬼。 笑死缓苛,一個胖子當(dāng)著我的面吹牛芳撒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播未桥,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼笔刹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冬耿?” 一聲冷哼從身側(cè)響起舌菜,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亦镶,沒想到半個月后日月,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袱瓮,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年爱咬,在試婚紗的時候發(fā)現(xiàn)自己被綠了尺借。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡精拟,死狀恐怖燎斩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜂绎,我是刑警寧澤栅表,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站师枣,受9級特大地震影響怪瓶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坛吁,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一劳殖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拨脉,春花似錦哆姻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至帖旨,卻和暖如春箕昭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背解阅。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工落竹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人货抄。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓述召,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蟹地。 傳聞我的和親對象是個殘疾皇子积暖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容