![探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案_第1頁(yè)](http://file4.renrendoc.com/view/91eef85e9b5827fa0bb4372c844a2866/91eef85e9b5827fa0bb4372c844a28661.gif)
![探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案_第2頁(yè)](http://file4.renrendoc.com/view/91eef85e9b5827fa0bb4372c844a2866/91eef85e9b5827fa0bb4372c844a28662.gif)
![探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案_第3頁(yè)](http://file4.renrendoc.com/view/91eef85e9b5827fa0bb4372c844a2866/91eef85e9b5827fa0bb4372c844a28663.gif)
![探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案_第4頁(yè)](http://file4.renrendoc.com/view/91eef85e9b5827fa0bb4372c844a2866/91eef85e9b5827fa0bb4372c844a28664.gif)
![探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案_第5頁(yè)](http://file4.renrendoc.com/view/91eef85e9b5827fa0bb4372c844a2866/91eef85e9b5827fa0bb4372c844a28665.gif)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、探討Ajax獲取表單值向Servlet傳遞的設(shè)計(jì)方案 現(xiàn)在JavaWeb領(lǐng)域,MVC框架越來(lái)越多,比較出名的有Struts、Struts2、SpringMVC、WebWork等。而Ajax,作為一種與特定的動(dòng)態(tài)Web編程語(yǔ)言(如Java、C#、PHP)無(wú)關(guān)的技術(shù),也已經(jīng)被引入到了Java MVC框架的各家各戶(hù)。而這些MVC框架,歸根到底,都是對(duì)Servlet技術(shù)的封裝。同時(shí),支持Ajax的JavaScript框架(or類(lèi)庫(kù))也越來(lái)越多,出名的如Jquery、Ext、Prototype、DWR等,而它們實(shí)現(xiàn)異步傳輸功能還是離不開(kāi)JavaScript中的XMLHttpRequest這個(gè)對(duì)象。好,轉(zhuǎn)
2、入正題吧。Ajax通過(guò)XMLHttpRequest對(duì)象實(shí)現(xiàn)異步傳輸,那我們首先要獲取這個(gè)對(duì)象。由于瀏覽器的差異,為了兼容各種常用的瀏覽器,先寫(xiě)一個(gè)初始化XMLHttpRequest對(duì)象的方法,代碼如下: Js代碼 /* * Get方式向服務(wù)器端異步發(fā)送數(shù)據(jù) * param url 服務(wù)器端的路徑,數(shù)據(jù)發(fā)送的目的地 * param data 發(fā)送的數(shù)據(jù),格式如: key1=value1&key2=value2 * param callback 回調(diào)函數(shù), */ function doGet(url, data, callback) var url = url; if(url.indexOf(?)
3、 = -1) url = url + ? + data; else url = url + & + data; initXmlHttp(); xmlHttp.onreadystatechange = callback; /注冊(cè)回調(diào)函數(shù) xmlHttp.open(GET, url, true); /設(shè)置連接信息 xmlHttp.send(null); /* * Post方式向服務(wù)器端異步發(fā)送數(shù)據(jù) * param url 服務(wù)器端的路徑,數(shù)據(jù)發(fā)送的目的地 * param data 發(fā)送的數(shù)據(jù),格式如: key1=value1&key2=value2 * param callback 回調(diào)函數(shù) *
4、return */ function doPost(url, data, callback) initXmlHttp(); /初始化 xmlHttp.onreadystatechange = callback; /注冊(cè)回調(diào)函數(shù) xmlHttp.open(POST, url, true); xmlHttp.setRequestHeader(Content-Type, application/x-www-form-urlencoded); xmlHttp.send(data); /* * 默認(rèn)回調(diào)函數(shù) * 只在測(cè)試時(shí)使用,在doGet和doPost函數(shù)中的第三個(gè)參數(shù)callback,可由用戶(hù)自定義
5、回調(diào)函數(shù), * 若不設(shè)定,則調(diào)用默認(rèn)的回調(diào)函數(shù) */ function callback() /判斷對(duì)象的狀態(tài)是否交互完成 if(xmlHttp.readyState = 4) /判斷http的交互是否成功 if(xmlHttp.status = 200) /獲取服務(wù)器返回的純文本數(shù)據(jù) var responseText = xmlHttp.responseText; /獲取服務(wù)器返回的XML格式數(shù)據(jù) /var responseXml = xmlHttp.responseXML; /Alert從服務(wù)器端返回的信息 window.alert(responseText); 對(duì)上面的代碼,在這里解析一
6、下:XMLHttpRequest對(duì)象的請(qǐng)求狀態(tài)(readyState)有0、1、2、3、4,其中,0表示未初始化,1表示open方法成功調(diào)用,2表示服務(wù)器應(yīng)答客戶(hù)端請(qǐng)求,3表示交互中,HTTP頭信息已經(jīng)收到,但響應(yīng)數(shù)據(jù)還沒(méi)有接收,4表示數(shù)據(jù)接收完成。我們通過(guò)“xmlHttp.onreadystatechange = callback;”來(lái)設(shè)置如果XMLHttpRequest對(duì)象的請(qǐng)求狀態(tài)發(fā)生改變了,則會(huì)執(zhí)行回調(diào)函數(shù)callback。我們可以看到,在callback方法體中,我們只關(guān)心readyState=4(交互完成)的情況,再獲取從服務(wù)器端返回的狀態(tài)碼status,常見(jiàn)的狀態(tài)碼有:200表示
7、交互成功,404表示頁(yè)面沒(méi)找到,500表示服務(wù)器處理錯(cuò)誤等。接著,通過(guò)XMLHttpRequest的responseText屬性得到從服務(wù)器端返回的文本數(shù)據(jù),或者通過(guò)responseXML屬性獲得XML格式的數(shù)據(jù)。在上面的代碼中,doGet方法和doPost方法都有參數(shù)”data”,它由XMLHttpRequest負(fù)責(zé)從客戶(hù)端傳送到服務(wù)器端,對(duì)于Get方法,附在URL尾部,例如:member.jsp?name=xxx&sex=male。對(duì)于Post方式,可調(diào)用XMLHttpRequest的send方法發(fā)送。data的數(shù)據(jù)形式比較靈活,可以是普通的參數(shù)格式、XML格式,JSON格式或者是其他格式
8、,只要你能發(fā)送過(guò)去,服務(wù)器端就有辦法將你解析出來(lái)。在這里,我們降低難度,就用最簡(jiǎn)單的參數(shù)格式,即key1=value1 & key2=value2 & key3=value3 & 我們都知道,HTTP協(xié)議的Get方式傳輸數(shù)據(jù),是通過(guò)把這些key-value串附到URL后面的,也就是我們只要點(diǎn)表單的提交按鈕,就可以看到地址欄后面會(huì)多了一串key-value,代表表單里各輸入框的名和值。然后,我們要做異步發(fā)送數(shù)據(jù),就不能用表單的自動(dòng)提交了,也就是說(shuō),得自己一個(gè)一個(gè)獲取到各輸入框的數(shù)據(jù),然后再一個(gè)一個(gè)拼成上面的key-value串再發(fā)送。有沒(méi)有一種簡(jiǎn)單的辦法來(lái)組織這些數(shù)據(jù)呢?大家看到key-valu
9、e是否會(huì)想到Java中的什么類(lèi)?請(qǐng)看下面代碼,我用JavaScript寫(xiě)了一個(gè)Map類(lèi)(JavaScript中的“function”可以看作是方法,也可以看作是面向?qū)ο蟮摹邦?lèi)”),就是類(lèi)似于Java中我們常用的Map接口。 Java代碼 /* * Map類(lèi) * 實(shí)現(xiàn)了類(lèi)似于Java語(yǔ)言中的Map接口的常用方法 */ function Map() /key集 this.keys = new Array(); /value集 this.values = new Array(); /添加key-value進(jìn)Map this.put = function(key, value) if(key = nu
10、ll | key = undefined) return; var length = this.size(); for(var i = 0 ; i length ; i + ) /如果keys數(shù)組中有相同的記錄,則不覆蓋原記錄的值 if(this.keysi = key) this.valuesi = value; this.keys.push(key); this.values.push(value); ; /獲取指定key的value this.get = function(key) var length = this.size(); for(var i = 0 ; i length ;
11、i + ) if(this.keysi = key) return this.valuesi; else continue; return null; ; /移除指定key所對(duì)應(yīng)的map this.remove = function(key) var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) while(i length - 1) this.keysi = this.keysi+1; this.valuesi = this.valuesi+1; i + ; /處理最后一個(gè)元素 this
12、.keys.pop(); this.values.pop(); break; ; /是否包含指定的key this.containsKey = function(key) var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) return true; return false; ; /是否包含指定的value this.containsValue = function(value) var length = this.size(); for(var i = 0 ; i length ; i
13、 + ) if(this.valuesi = value) return true; return false; ; /包含記錄總數(shù) this.size = function() return this.keys.length; ; /是否為空 this.isEmpty = function() return this.size() = 0 ? true : false; ; /清空Map this.clear = function() this.keys = new Array(); this.values = new Array(); ; /將map轉(zhuǎn)成字符串,格式:key1=value1
14、,key2=value2 this.toString = function() var length = this.size(); var str = ; for(var i = 0 ; i length ; i + ) str = str + this.keysi + = + this.valuesi; if(i != length-1) str += ,; return str; ; 代碼比較長(zhǎng),有些方法在本例中可能用不到,但也寫(xiě)出來(lái)了,或者在其他地方可能有用吧。當(dāng)我們使用這個(gè)Map類(lèi)來(lái)存儲(chǔ)HTTP的參數(shù)時(shí),發(fā)覺(jué)有幾個(gè)不妥的地方:一是put方法,在Java的Map接口中,是不允許有重復(fù)的k
15、ey存在的,而在JavaScript中作為傳輸參數(shù)的載體時(shí),很多時(shí)候會(huì)出現(xiàn)多個(gè)同名的key的,例如處理表單的checkbox時(shí),同一個(gè)name的有幾個(gè)checkbox,構(gòu)成一個(gè)復(fù)選框組,組織參數(shù)時(shí)就形如“key=value1&key=value2”,故put方法必須改。也是由于這個(gè)原因,get方法和remove方法也要改。二是toString方法,key=value對(duì),不是用“,”號(hào)隔開(kāi)的,而是用“&”號(hào),故toString方法也須改。而有時(shí)候想想,如果把Map類(lèi)改了,如果其他地方要用到的話(huà),是不是還是改回來(lái),與其改來(lái)改去的,不如繼承它,重寫(xiě)put、get、remove和toString方法。
16、好主意,代碼如下:Js代碼 /* * ParamMap類(lèi),用于存儲(chǔ)HTTP請(qǐng)求中的Get方法或者Post方法所傳遞的參數(shù) * 繼承于Map類(lèi),但改寫(xiě)一些方法,以適合HTTP請(qǐng)求中的參數(shù)格式 * 與Map不同之處有:ParamMap允許多個(gè)同名的key存在, * toString方法返回的key=value對(duì)以&號(hào)連接,而不是,號(hào),等等。 */ function ParamMap() /繼承Map類(lèi) Map.call(this); /重寫(xiě)put方法,允許多個(gè)同名key存在 this.put = function(key, value) if(key = null | key = undefine
17、d) return; this.keys.push(key); this.values.push(value); ; /重寫(xiě)get方法,返回values數(shù)組 this.get = function(key) var results = new Array(); var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) results.push(this.valuesi); return results; ; /重寫(xiě)remove方法 this.remove = function(key) var
18、 length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) while(i length - 1) this.keysi = this.keysi+1; this.valuesi = this.valuesi+1; i + ; /處理最后一個(gè)元素 this.keys.pop(); this.values.pop(); ; /重寫(xiě)toString方法, 轉(zhuǎn)成XMLHttpRequest.send(ajaxString)方法的參數(shù)格式的字符串, /形如:key1=value1&key2=value2 th
19、is.toString = function() var length = this.size(); var str = ; for(var i = 0 ; i length ; i + ) str = str + this.keysi + = + this.valuesi; if(i != length-1) str += &; return str; ; 怎么使用這個(gè)ParamMap類(lèi)呢,且看下面的示例代碼:Js代碼 var username = document.getElementById(username).value; var password = document.getElem
20、entById(password).value; var sex = document.getElementById(sex).value; var map = new ParamMap(); map.put(username, username); map.put(password, password); map.put(sex, sex); doGet(test/register, map.toString(), callback); doPost(test/register, map.toString(), callback); Js代碼 在JavaScript中,用來(lái)獲取HTML結(jié)點(diǎn)的
21、方法,常用的有如下方法:Js代碼 Node document.getElementById(username) /根據(jù)標(biāo)簽的id NodeList document.getElementsByName(“username”) /根據(jù)標(biāo)簽的name NodeList document.getElementsByTagName(input) /根據(jù)標(biāo)簽的標(biāo)簽名 我們注意到在除了getElementById是返回Node對(duì)象外,其他兩個(gè)方法都是返回NodeList對(duì)象,相當(dāng)于Node數(shù)組。在Ajax應(yīng)用中,根據(jù)ID來(lái)獲取節(jié)點(diǎn),很多時(shí)候十分方便,如獲取text、password、hidden、text
22、area類(lèi)型的值,但有時(shí)候并不那么方便,如處理checkbox、radio(不允許多個(gè)同名的id)。況且有許多情況下,開(kāi)發(fā)者是由“非Ajax”轉(zhuǎn)成Ajax應(yīng)用的。在還沒(méi)有引進(jìn)Ajax的時(shí)候,表單傳值都是根據(jù)輸入域的name的值來(lái)區(qū)分的,不管是Get方式還是Post方式,在服務(wù)器端(這里指Java Servlet)獲取數(shù)據(jù)的代碼如下:Java代碼 String HttpServletRequest.getParameter(keyName); /用于單值表單域 String HttpServletRequest.getParameterValues(keyName); /用于多值表單域 所謂的“
23、單值表單域”就是上面提到過(guò)的type為text、password、hidden的input或者textarea等,而“多值表單域”是指checkbox。其實(shí),也不盡然,如單值表單域有時(shí)候也可以是多值表單域,如我們注冊(cè)時(shí)有時(shí)會(huì)要求填多個(gè)郵箱,這個(gè)就可以重復(fù)多行用同一個(gè)name,它在Servlet端獲取值方式跟checkbox一樣處理。鑒于各種原因,我們?cè)贘avaScript獲取HTML Form表單域方法,決定采用getElementsByName方法,這樣,我們是不是每取一個(gè)表單元素,就得將NodeList類(lèi)型的返回結(jié)果遍歷一遍,獲取Node,再?gòu)腘ode獲取值呢?既然選擇了這樣做,當(dāng)然少不了
24、這樣的工作,不過(guò),我們可以寫(xiě)一個(gè)可重用的方法,讓它處理一下NodeList對(duì)象。且看代碼: Js代碼 /* * 獲取nodeList的值集 * param nodeList Node數(shù)組,可通過(guò)getElementsByName或者getElementsByTagName等方法獲得 * return 值數(shù)組 */ function nodeList2ValuesArray(nodeList) /結(jié)果值數(shù)組,形如:aaa,bbb,ccc var values = new Array(); var length = nodeList.length; var nodeName = nodeList.
25、item(0).nodeName; /對(duì)的處理 if(nodeName = INPUT) var type = nodeList.item(0).getAttribute(type); if(type = text | type = password | type = hidden) for(var i = 0 ; i length ; i + ) values.push(nodeList.item(i).value); else if(type = checkbox | type = radio) for(var i = 0 ; i length ; i + ) var node = nod
26、eList.item(i); if(node.checked) values.push(node.value); /對(duì)xxx的處理 else if(nodeName = TEXTAREA) for(var i = 0 ; i length ; i + ) values.push(nodeList.item(i).value); /對(duì)的處理 else if (nodeName = SELECT) var subNodeList = nodeList.item(0).getElementsByTagName(option); return nodeList2ValuesArray(subNodeL
27、ist); /對(duì)的子元素xxx的處理 else if (nodeName = OPTION) for(var i = 0 ; i length ; i + ) var node = nodeList.item(i); if(node.selected) values.push(node.value); return values; 上面代碼將NodeList轉(zhuǎn)成了值數(shù)組,而且讓使用者忽略表單域類(lèi)型的差異,專(zhuān)心于值的獲取和使用。美中不足的是,上面的方法返回的是數(shù)組,我們還是一個(gè)一個(gè)遍歷再拼成key=value字符串。接下來(lái)的方法不但解決了這一點(diǎn),而且還大大簡(jiǎn)化我們的表單取值,且看: Js代碼 /
28、* * 解析表單的數(shù)據(jù),轉(zhuǎn)成ParamMap的形式 * param 任意個(gè)參數(shù),代表表單子元素的name值 * return ParamMap結(jié)果集 */ function parseForm2ParamMap() var map = new ParamMap(); /參數(shù)的長(zhǎng)度,注意:方法定義的括號(hào)中雖然沒(méi)有定義參數(shù),但卻可以設(shè)任意多個(gè)參數(shù) var length = arguments.length; for(var i = 0 ; i length ; i + ) var nodeList = document.getElementsByName(argumentsi); var valu
29、es = nodeList2ValuesArray(nodeList); for(var j = 0 ; j values.length ; j + ) map.put(argumentsi, valuesj); return map; 這個(gè)方法返回值的類(lèi)型是ParamMap,也就是我們剛才定義的用來(lái)傳遞參數(shù)的類(lèi),這個(gè)類(lèi)中有一個(gè)toString的方法,不就是返回“key1=value1&key2=value2”形式的字符串嗎?OK,下面的測(cè)試?yán)樱瑢⑸婕暗奖韱蔚母鞣N元素域,其中引進(jìn)了ajax.js文件,其內(nèi)容即是我們上面所寫(xiě)的JS函數(shù)和類(lèi),在附件中可下載到,在此就不重復(fù)貼出來(lái)了。且看HTML代
30、碼: Html代碼 測(cè)試Ajax與Servlet之間的數(shù)據(jù)傳遞 window.onload = function() var submit = document.getElementById(submit); submit.onclick = function() var map = parseForm2ParamMap(username, email, password, userid, sex, framework, salary, dream); /doPost(input, map.toString(), callback); /默認(rèn)Alert出信息 doPost(input, map
31、.toString(), function() if(xmlHttp.readyState = 4) if(xmlHttp.status = 200) var returnMsg = document.getElementById(returnMsg); returnMsg.innerHTML = xmlHttp.responseText; ); ; ; 測(cè)試Ajax與Servlet之間的數(shù)據(jù)傳遞(Step1:從Client-Server) 你的姓名: 你的電子郵件(可填兩個(gè)): 郵件地址1: 郵件地址2: 你的密碼: 你的性別 : 男 女 你掌握的開(kāi)源框架 : Struts Spring H
32、ibernate iBatis WebWork 你的薪水范圍 : 2000以下 20003000 30004000 40005000 5000以上 你的職業(yè)夢(mèng)想: 服務(wù)器端的代碼如下:Java代碼 package simple.rongxh.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServle
33、tRequest; import javax.servlet.http.HttpServletResponse; /* * RongXinHua心夢(mèng)帆影 * site1: * site2: /rongxh7 * author rongxinhua * */ public class Input extends HttpServlet private static final long serialVersionUID = 1L; private void process(HttpServletRequest request, HttpServletResponse response) thro
34、ws ServletException, IOException /獲取數(shù)據(jù) request.setCharacterEncoding(UTF-8); String username = request.getParameter(username); String emails = request.getParameterValues(email); String password = request.getParameter(password); String userid = request.getParameter(userid); String sex = request.getPar
35、ameter(sex); String framework = request.getParameterValues(framework); String salary = request.getParameter(salary); String dream = request.getParameter(dream); /響應(yīng)給客戶(hù)端 response.setContentType(text/html;charset=UTF-8); PrintWriter out = response.getWriter(); out.append(恭喜你,保存成功,你的基本信息如下:); out.appen
36、d(姓名: + username + ); for(int i = 0 ; i emails.length ; i + ) out.append(郵箱 + (i+1) + : + emailsi + ); out.append(密碼: + password + ); out.append(編號(hào): + userid + ); out.append(性別: + sex + ); out.append(框架:); for(int i = 0 ; framework != null & i framework.length ; i + ) out.append(frameworki + ); out.
37、append(); out.append(薪水: + salary + ); out.append(夢(mèng)想: + dream + ); out.println(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException process(request, response); protected void doPost(HttpServletRequest request, HttpServletResponse resp
38、onse) throws ServletException, IOException process(request, response); 運(yùn)行結(jié)果截圖如下:附錄資料:從 XML 生成可與 Ajax 共同使用的 JSON時(shí)下,非常流行使用 JavaScript 代碼為數(shù)據(jù)驅(qū)動(dòng)的 Web 應(yīng)用程序添加互動(dòng)性。若能將數(shù)據(jù)編碼成 JavaScript Object Notation(JSON)的格式,您就可以更輕松地通過(guò) JavaScript 語(yǔ)言使用它。通過(guò)本文,發(fā)掘使用 XSLT V2 從 XML 數(shù)據(jù)生成 JSON 的幾種不同方法。幾年前,許多開(kāi)發(fā)人員很看好 XML、XSLT、Extensi
39、ble HTML (XHTML)和其他一些基于標(biāo)記的語(yǔ)言。現(xiàn)在,Asynchronous JavaScript and XML(AJAX)成了新的熱點(diǎn),人們又將目光轉(zhuǎn)向了使用 JavaScript 代碼的數(shù)據(jù)驅(qū)動(dòng)的富 Internet 應(yīng)用程序。但是開(kāi)發(fā)人員是否已經(jīng)消除了 XML 和這一新技術(shù)之間的鴻溝呢?當(dāng)然,您可以在 Web 客戶(hù)機(jī)中使用 XML 解析器來(lái)讀取數(shù)據(jù),但這種做法會(huì)帶來(lái)兩個(gè)問(wèn)題。第一,出于安全方面的原因,XML 數(shù)據(jù)只能從與此頁(yè)面相同的那個(gè)域中讀取。這雖然不是什么大的限制因素,但它的確會(huì)引起部署方面的問(wèn)題,還會(huì)阻礙 DHTML 小部件的創(chuàng)建。第二,讀取和解析 XML 會(huì)非常慢。
40、另一種做法是讓服務(wù)器執(zhí)行 XML 的解析工作,方法是設(shè)置服務(wù)器,使之向?yàn)g覽器發(fā)送以 JavaScript 代碼或時(shí)下流行的 JavaScript Object Notation(JSON)編碼的數(shù)據(jù)。本文將展示如下三種使用 XSLT V2 語(yǔ)言和 Saxon XSLT V2 處理器從 XML 數(shù)據(jù)生成 JSON 的技巧: 簡(jiǎn)單編碼 通過(guò)函數(shù)調(diào)用加載數(shù)據(jù) 編碼對(duì)象 JSON 簡(jiǎn)介要學(xué)習(xí)如何將數(shù)據(jù)編碼成 JSON(它只是 JavaScript 的一個(gè)子集),最好的方法是從數(shù)據(jù)開(kāi)始。清單 1 顯示了書(shū)籍列表的一個(gè)示例 XML 數(shù)據(jù)集。清單 1. 基本的圖形化圖書(shū)館 Code Generation i
41、n Action JackHerrington Manning PHP Hacks JackHerrington OReilly Podcasting Hacks JackHerrington OReilly 這個(gè)數(shù)據(jù)集很簡(jiǎn)單,只包含三本書(shū),每本書(shū)都具有惟一的 ID、書(shū)名、作者姓名及出版商的名字。(沒(méi)錯(cuò),我只選擇了我自己的書(shū)作為數(shù)據(jù)集,但能怨我嗎?這些書(shū)實(shí)在是不可多得的節(jié)日和生日禮物。)清單 2 顯示了這些數(shù)據(jù)在 JSON 中的效果。清單 2. JSON 中的示例數(shù)據(jù)集 id: 1, title: Code Generation in Action, first: Jack, last: He
42、rrington, publisher: Manning , . 方括號(hào) () 表明這是一個(gè)數(shù)組。大括號(hào) () 則表明這是一個(gè)散列表,該散列表由一組名稱(chēng)和值對(duì)組成。在本例中,我創(chuàng)建了一個(gè)散列表的數(shù)組 用來(lái)存儲(chǔ)這類(lèi)結(jié)構(gòu)式數(shù)據(jù)的一種常見(jiàn)方法。另外一點(diǎn)值得注意的是字符串是通過(guò)單引號(hào)或雙引號(hào)被編碼的。所以,如果我想用單引號(hào)編碼 OReilly,我就必須使用反斜杠對(duì)它進(jìn)行轉(zhuǎn)義:OReilly。 這讓我編寫(xiě)的這個(gè) XSLT 樣式表更為有趣了一些。我并未在本例中放上任何日期,但您也可以通過(guò)如下兩種方法來(lái)編碼日期。第一種方法是將日期作為字符串,該字符串必須在后面被解析。第二種方法是將日期作為一個(gè)對(duì)象,比如:p
43、ublishdate: new Date( 2006, 6, 16, 17, 45, 0 )這段代碼將 publishdate 的值設(shè)置為6/16/2006 5:45:00 p.m.。簡(jiǎn)單編碼接下來(lái)我將陸續(xù)介紹 JSON 編碼的幾種技巧。第一種也是其中最簡(jiǎn)單的一種,此樣式表如 清單 3 所示。清單 3. simple.xsl 樣式表 var g_books = 1, id: ,name: ,first: ,last: ,publisher: ;要理解此樣式表,不妨先來(lái)看一下 清單 4 所示的輸出。清單 4. simple.xsl 的輸出var g_books = id: 1,name: Cod
44、e Generation in Action,first: Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: Herrington,publisher: OReilly;這里,我將名為 g_books 的變量設(shè)置為一個(gè)包含三個(gè)散列表的數(shù)組,每個(gè)散列表包含關(guān)于該書(shū)的信息。再回過(guò)頭來(lái)看看 清單 3,您會(huì)發(fā)現(xiàn)第一個(gè)模板匹配 / 路徑,
45、它也是首先應(yīng)用到輸入數(shù)據(jù)集的模板,該模板使用 for-each 循環(huán)來(lái)遍歷每本書(shū)。之后,它使用 標(biāo)記來(lái)將文本從該數(shù)據(jù)輸出到 JavaScript 輸出代碼。對(duì)于字符串,我使用名為 js:escape() 的定制函數(shù),它在模板之前定義。該函數(shù)使用一個(gè)正則表達(dá)式將一個(gè)單引號(hào)標(biāo)記更改為帶有反斜杠的單引號(hào)標(biāo)記。最后一個(gè)重要的元素是 標(biāo)記,它告知處理器要輸出的是文本而不是 XML。要檢驗(yàn)此過(guò)程是否可以正常工作,我加入了一個(gè) simple .html 文件,該文件引用我在 simple.js 保存的 XSL 樣式表的輸出。這個(gè) HTML 文件如 清單 5 所示。清單 5. simple.html 文件Si
46、mple JS loaderdocument.write( Found +g_books.length+ books );.html 文件使用 標(biāo)記簡(jiǎn)單地加載已編碼了的 JavaScript 代碼。之后,第二個(gè) 標(biāo)記將數(shù)組的長(zhǎng)度寫(xiě)出到瀏覽器頁(yè)面,如 圖 1 所示。圖 1. simple.html 的輸出好了!數(shù)據(jù)文件包含三本書(shū),相應(yīng)的 JavaScript 文件也包含三本書(shū)。它真的可以工作!通過(guò)函數(shù)加載上述第一個(gè)示例很簡(jiǎn)單,而且在大多數(shù)情況下可以發(fā)揮其作用,但它存在一些問(wèn)題。第一個(gè)問(wèn)題是對(duì)于數(shù)據(jù)何時(shí)被加載沒(méi)有任何提示。如果數(shù)據(jù)是像頁(yè)面那樣被靜態(tài)加載的,這不成問(wèn)題。但是如果頁(yè)面動(dòng)態(tài)創(chuàng)建了一個(gè) 標(biāo)
47、記來(lái)按需加載數(shù)據(jù),那么就很有必要知道 標(biāo)記是何時(shí)完成的。實(shí)現(xiàn)此功能的最好的方法是讓編碼了的數(shù)據(jù)調(diào)用一個(gè) JavaScript 函數(shù),而不是只設(shè)置數(shù)據(jù)。這個(gè)概念很重要,所以我將花一些時(shí)間來(lái)介紹一下為什么您必須要通過(guò)動(dòng)態(tài)生成的 標(biāo)記來(lái)加載數(shù)據(jù)。頁(yè)面加載后,從服務(wù)器獲得數(shù)據(jù)是 Web 2.0 的核心功能。一種方法是使用 AJAX 機(jī)制通過(guò)到服務(wù)器的調(diào)用來(lái)加載 XML。然而,出于安全性的原因,AJAX 機(jī)制只限于從單一域獲取數(shù)據(jù)。這在大多數(shù)情況下都沒(méi)有問(wèn)題,但有時(shí),您可能需要 JavaScript 代碼運(yùn)行在他人的頁(yè)面上(例如,Google Maps)。在這種情況下從服務(wù)器獲得數(shù)據(jù)的惟一方法是通過(guò)動(dòng)態(tài)
48、加載 標(biāo)記。獲悉 標(biāo)記何時(shí)加載的最好的方法是讓 標(biāo)記返回的腳本調(diào)用函數(shù)而不是簡(jiǎn)單地加載數(shù)據(jù)。清單 6 顯示了在函數(shù)調(diào)用中編碼的數(shù)據(jù)。清單 6. Function1.jsAddBooks( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: H
49、errington,publisher: OReilly );清單 7 給出了相應(yīng)的 .html 文件。清單 7. Function1.htmlFunction 1 JS loadervar g_books = ;function AddBooks( books ) g_books = books; drawbooks( g_books );稍后將詳細(xì)介紹 drawbooks 函數(shù)。這里重要的是了解一下頁(yè)面如何定義 AddBooks 函數(shù),該函數(shù)隨后會(huì)由 function1.js 文件中的腳本調(diào)用。該 AddBooks 函數(shù)負(fù)責(zé)處理數(shù)據(jù)。而且被調(diào)用的 AddBooks 函數(shù)會(huì)向頁(yè)面指示 標(biāo)記被
50、正確加載,并已加載完成。要?jiǎng)?chuàng)建 function1.js 文件,我只對(duì)樣式表稍微做了一點(diǎn)修改,如 清單 8 所示。清單 8. function1.xsl 樣式表AddBooks( 1, id: ,name: ,first: ,last: ,publisher: );這里,我調(diào)用了一個(gè)函數(shù),而不是簡(jiǎn)單地設(shè)置一個(gè)變量。這就是我所做的惟一更改。回到頁(yè)面,我使用了 drawbooks 函數(shù)來(lái)構(gòu)建書(shū)的表格,這樣我就能夠確認(rèn)數(shù)據(jù)被正確編碼和正確顯示。此函數(shù)是在 drawbooks.js 內(nèi)定義的,如 清單 9 所示。清單 9. Drawbooks.jsfunction drawbooks( books )
51、 var elTable = document.createElement( table ); for( var b in books ) var elTR = elTable.insertRow( -1 ); var elTD1 = elTR.insertCell( -1 ); elTD1.appendChild( document.createTextNode( booksb.id ) ); var elTD2 = elTR.insertCell( -1 ); elTD2.appendChild( document.createTextNode( ) ); var
52、elTD3 = elTR.insertCell( -1 ); elTD3.appendChild( document.createTextNode( booksb.first ) ); var elTD4 = elTR.insertCell( -1 ); elTD4.appendChild( document.createTextNode( booksb.last ) ); var elTD5 = elTR.insertCell( -1 ); elTD5.appendChild( document.createTextNode( booksb.publisher ) ); document.b
53、ody.appendChild( elTable );這個(gè)簡(jiǎn)單函數(shù)創(chuàng)建了一個(gè)表格節(jié)點(diǎn),然后循環(huán)訪(fǎng)問(wèn)書(shū)的列表并為每本書(shū)創(chuàng)建一行,為每個(gè)數(shù)據(jù)元素分配一個(gè)單元格。此頁(yè)面上的代碼的結(jié)果如 圖 2 所示。圖 2. function1.html 的結(jié)果現(xiàn)在我就可以查看一下此頁(yè)面的輸出并確認(rèn)來(lái)自原始 .xml 文件的一切均已被正確轉(zhuǎn)換成 JavaScript 代碼,且數(shù)據(jù)被發(fā)送到 AddData 函數(shù)并被正確添加到頁(yè)面。細(xì)化函數(shù)調(diào)用技術(shù)我很喜歡函數(shù)調(diào)用這一技術(shù),但我并不贊同將所有圖書(shū)數(shù)據(jù)都放入一個(gè)塊中。另一種方式是為每條記錄采用一個(gè)調(diào)用,如 清單 10 所示。清單 10. Function2.jsAddBo
54、ok( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning );AddBook( id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly );.對(duì) .html 頁(yè)面只需做少許修改,如 清單 11 所示。清單 11. Function2.html.var g_books = ;function AddBook( book ) g_books.push( book ); .這里更改了 XSLT,以
55、使函數(shù)調(diào)用駐留在 for-each 循環(huán)體內(nèi)。清單 12 顯示了更新后的樣式表。清單 12. function2.xsl.AddBook( id: ,name: ,first: ,last: ,publisher: );.對(duì)這個(gè)給定示例來(lái)說(shuō),這種更改看起來(lái)有些隨意。但如果原始的 XML 數(shù)據(jù)集有多種數(shù)據(jù)類(lèi)型,要為每種類(lèi)型分配一個(gè)單獨(dú)的函數(shù)調(diào)用會(huì)使 XSL 和頁(yè)面上的 JavaScript 代碼更為簡(jiǎn)單、更易于維護(hù)。編碼對(duì)象對(duì)小的頁(yè)面來(lái)講,使用 JavaScript 函數(shù)沒(méi)有問(wèn)題。但對(duì)于大型項(xiàng)目,就需要使用 JavaScript 語(yǔ)言的一些面向?qū)ο筇匦?。是的,JavaScript 語(yǔ)言可以處理對(duì)象而且可以處理得很好。清單 13 顯示了如何創(chuàng)建帶有數(shù)據(jù)的對(duì)象。清單 13. Object1.jsg_books.push( new Book( id: 1,name: Code Generation in Action,fir
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年合作伙伴入住合同范本
- 2025年勞動(dòng)合同和社保協(xié)議中工傷保險(xiǎn)的細(xì)節(jié)
- 2025年辦公文具用品供貨合同范文
- 2025年基礎(chǔ)設(shè)施建設(shè)監(jiān)理框架協(xié)議
- 2025年養(yǎng)殖戶(hù)種牛交易申請(qǐng)協(xié)議范本
- 2025年采購(gòu)合同簽訂與風(fēng)險(xiǎn)控制
- 2025年企業(yè)結(jié)構(gòu)重組協(xié)議書(shū)模板
- 2025年住宿生校園安全責(zé)任協(xié)議
- 2025年企業(yè)兼職外貿(mào)業(yè)務(wù)員招聘協(xié)議
- 2025年專(zhuān)利申請(qǐng)輔導(dǎo)合作協(xié)議
- 2024黑龍江公務(wù)員考試【A類(lèi)、B類(lèi)、省直、筆試】四套真題及答案
- 2025年中國(guó)高價(jià)HPV疫苗行業(yè)競(jìng)爭(zhēng)格局分析及投資規(guī)劃研究報(bào)告
- 醫(yī)院感染與醫(yī)療器械消毒
- 2025年春新北師大版物理八年級(jí)下冊(cè)課件 第七章 運(yùn)動(dòng)和力 第四節(jié) 同一直線(xiàn)上二力的合成
- 智能客服系統(tǒng)中人工智能技術(shù)的應(yīng)用
- 2025年公司年會(huì)活動(dòng)總結(jié)樣本(3篇)
- 村衛(wèi)生室2025年初工作計(jì)劃
- 派出所校園安全創(chuàng)新
- 飛書(shū)項(xiàng)目管理
- 醫(yī)院醫(yī)共體2025年度工作計(jì)劃
- UL498標(biāo)準(zhǔn)中文版-2019插頭插座UL標(biāo)準(zhǔn)中文版
評(píng)論
0/150
提交評(píng)論