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就可以得到所有的用戶信息了恕刘!效果如下:
前臺的數(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");
}