強(qiáng)烈推薦-ajax開發(fā)者必看的文章第3/3頁
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>無標(biāo)題文檔</title> <script language="javascript"> function loadXML(handler) { var url = "employees.xml"; if(document.implementation&&document.implementation.createDocument) { var xmldoc = document.implementation.createDocument("", "", null); xmldoc.onload = handler(xmldoc, url); xmldoc.load(url); } else if(window.ActiveXObject) { var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); xmldoc.onreadystatechange = function() { if(xmldoc.readyState == 4) handler(xmldoc, url); } xmldoc.load(url); } } function makeTable(xmldoc, url) { var table = document.createElement("table"); table.setAttribute("border","1"); table.setAttribute("width","600"); table.setAttribute("class","tab-content"); document.body.appendChild(table); var caption = "Employee Data from " + url; table.createCaption().appendChild(document.createTextNode(caption)); var header = table.createTHead(); var headerrow = header.insertRow(0); headerrow.insertCell(0).appendChild(document.createTextNode("姓名")); headerrow.insertCell(1).appendChild(document.createTextNode("職業(yè)")); headerrow.insertCell(2).appendChild(document.createTextNode("工資")); var employees = xmldoc.getElementsByTagName("employee"); for(var i=0;i<employees.length;i++) { var e = employees[i]; var name = e.getAttribute("name"); var job = e.getElementsByTagName("job")[0].firstChild.data; var salary = e.getElementsByTagName("salary")[0].firstChild.data; var row = table.insertRow(i+1); row.insertCell(0).appendChild(document.createTextNode(name)); row.insertCell(1).appendChild(document.createTextNode(job)); row.insertCell(2).appendChild(document.createTextNode(salary)); } } </script> <link href="css/style.css" rel="stylesheet" type="text/css"> </head> <body onLoad="loadXML(makeTable)"> </body> </html>7.5、處理XML文檔
供讀取調(diào)用的XML文檔 – employees.xml:
<?xml version="1.0" encoding="gb2312"?> <employees> <employee name="J.Doe"> <job>Programmer</job> <salary>32768</salary> </employee> <employee name="A.Baker"> <job>Sales</job> <salary>70000</salary> </employee> <employee name="Big Cheese"> <job>CEO</job> <salary>100000</salary> </employee> </employees>
脫離XML文檔的AJAX是不完整的。在本部分未完成之前,有讀者說AJAX改名叫AJAH(H應(yīng)該代表HTML吧)比較合適。應(yīng)該承認(rèn),XML文檔在數(shù)據(jù)的結(jié)構(gòu)化表示以及接口對接上有先天的優(yōu)勢,但也不是所有的數(shù)據(jù)都應(yīng)該用XML表示。有些時候單純的文本表示可能會更合適。下面先舉個AJAX處理返回XML文檔的例子再討論什么時候使用XML。
7.5.1、處理返回的XML
例子8 -- sample7_1.htm:
在這個例子中,我們采用之前確定的AJAX開發(fā)框架,稍微修改一下body內(nèi)容和processRequest的相應(yīng)方式,將先前的employees.xml的內(nèi)容讀取出來并顯示。
body的內(nèi)容如下:
<input type="button" name="read" value="讀取XML" onClick="send_request('employees.xml')"> processRequest()方法修改如下: // 處理返回信息的函數(shù) function processRequest() { if (http_request.readyState == 4) { // 判斷對象狀態(tài) if (http_request.status == 200) { // 信息已經(jīng)成功返回,開始處理信息 var returnObj = http_request.responseXML; var xmlobj = http_request.responseXML; var employees = xmlobj.getElementsByTagName("employee"); var feedbackStr = ""; for(var i=0;i<employees.length;i++) { // 循環(huán)讀取employees.xml的內(nèi)容 var employee = employees[i]; feedbackStr += "員工:" + employee.getAttribute("name"); feedbackStr += " 職位:" + employee.getElementsByTagName("job")[0].firstChild.data; feedbackStr += " 工資:" + employee.getElementsByTagName("salary")[0].firstChild.data; feedbackStr += "\r\n"; } alert(feedbackStr); } else { //頁面不正常 alert("您所請求的頁面有異常。"); } } }
運(yùn)行一下,看來效果還不錯:
現(xiàn)在的web應(yīng)用程序往往采用了MVC三層剝離的設(shè)計方式。XML作為一種數(shù)據(jù)保存、呈現(xiàn)、交互的文檔,其數(shù)據(jù)往往是動態(tài)生成的,通常由JavaBean轉(zhuǎn)換過來。由JavaBean轉(zhuǎn)換成XML文檔的方式有好幾種,選擇合適的轉(zhuǎn)換方式往往能達(dá)到事半功倍的效果。下面介紹兩種常用的方式,以便需要的時候根據(jù)情況取舍。
A、類自行序列化成XML
類自行序列化成XML即每個類都實(shí)現(xiàn)自己的toXML()方法,選擇合適的API、適當(dāng)?shù)腦ML結(jié)構(gòu)、盡量便捷的生成邏輯快速生成相應(yīng)的XML文檔。顯然,這種方式必須要求每個類編寫專門的XML生成代碼,每個類只能調(diào)用自己的toXML()方法。應(yīng)用諸如JDOM等一些現(xiàn)成的API,可以減少不少開發(fā)投入。例子9是一個利用JDOM的API形成的toXML()方法。
例子9 -- toXml() 的 JDOM 實(shí)現(xiàn) -- Employ類的toXml()方法:
public Element toXml() { Element employee = new Element(“employee”); Employee.setAttribute(“name”,name); Element jobE = new Element(“job”).addContent(job); employee.setContent(jobE); Element salaryE = new Element(“salary”).addContent(salary); employee.setContent(salaryE); return employee; }
JDOM提供了現(xiàn)成的API,使得序列化成XML的工作更加簡單,我們只需要把toXML()外面包裝一個Document,然后使用XMLOutputter把文檔寫入servlet就可以了。toXml()允許遞歸調(diào)用其子類的toXML()方法,以便生成包含子圖的XML文檔。
使用類自行序列化成XML的方式,要每個類都實(shí)現(xiàn)自己的toXML()方法,而且存在數(shù)據(jù)模型與視圖耦合的問題,即要么為每個可能的視圖編寫?yīng)毩⒌膖oXML()方法,要么心甘情愿接收冗余的數(shù)據(jù),一旦數(shù)據(jù)結(jié)構(gòu)或者文檔發(fā)生改變,toXML()就要做必要的修改。
B、頁面模板生成XML方式
一般的,可以采用通用的頁面模板技術(shù)來生成XML文檔,這個XML文檔可以符合任何需要的數(shù)據(jù)模型,供AJAX靈活的調(diào)用。另外,模板可以采用任何標(biāo)記語言編寫,提高工作效率。下面是一個采用Struts標(biāo)簽庫編寫的XML文檔,輸出之前提到的employees.xml:
Sample8_2.jsp:
<%@ page contentType="application/xml; charset=gb2312" import="Employee"%> <%@ page import="java.util.Collection,java.util.ArrayList"%> <?xml version="1.0"?> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%> <% Employee em1 = new Employee(); em1.setName("J.Doe"); em1.setJob("Programmer"); em1.setSalary("32768"); Employee em2 = new Employee(); em2.setName("A.Baker"); em2.setJob("Sales"); em2.setSalary("70000"); Employee em3 = new Employee(); em3.setName("Big Cheese"); em3.setJob("CEO"); em3.setSalary("100000"); Collection employees = new ArrayList(); employees.add(em1); employees.add(em2); employees.add(em3); pageContext.setAttribute("employees",employees); %> <employees> <logic:iterate name="employees" id="employee"> <employee name="<bean:write name='employee' property='name'/>"> <job><bean:write name="employee" property="job"/></job> <salary><bean:write name="employee" property="salary"/></salary> </employee> </logic:iterate> </employees>
采用頁面模板生成XML方式,需要為每個需要的的數(shù)據(jù)模型建立一個對立的JSP文件,用來生成符合規(guī)范的XML文檔,而不能僅僅在類的toXML()方法中組織對象圖來實(shí)現(xiàn)。不過,倒是可以更加方便的確保標(biāo)記匹配、元素和屬性的順序正確以及XML實(shí)體正確轉(zhuǎn)義。
參考資料中Philip McCarthy的文章還描述了一種Javascript對象標(biāo)注的生成方式,本文在此不贅述。有興趣的讀者可以自行查看了解。
7.5.3、如何在使用XML還是普通文本間權(quán)衡使用XML文檔確實(shí)有其方便之處。不過XML文檔的某些問題倒是要考慮一下,比如說延遲,即服務(wù)器不能立即解析XML文檔成為DOM模型。這個問題在一定程度上會影響AJAX要求的快速反應(yīng)能力。另外,某些情況下我們并不需要使用XML來表示數(shù)據(jù),比如說數(shù)據(jù)足夠簡單成只有一個字符串而已。就好像我們之前提到的數(shù)據(jù)校驗(yàn)和級聯(lián)菜單的例子一樣。所以,個人認(rèn)為在下面這些情況下可以考慮使用XML來作為數(shù)據(jù)表示的介質(zhì):
- 數(shù)據(jù)比較復(fù)雜,需要用XML的結(jié)構(gòu)化方式來表示
- 不用考慮帶寬和處理效率支出
- 與系統(tǒng)其他API或者其他系統(tǒng)交互,作為一種數(shù)據(jù)中轉(zhuǎn)中介
- 需要特定各式的輸出視圖而文本無法表示的
總之,要認(rèn)真評估兩種表示方式的表示成本和效率,選擇合適的合理的表示方式?! ?nbsp;
在關(guān)于AJAX的系列文章的下一篇,我們將綜合使用DOM和XML,來實(shí)現(xiàn)一個可以持久化的簡單留言簿。另外,還將試著模擬MSN Space的部分功能,來體會AJAX的魅力。
參考文章:作者: | fanscial | 標(biāo)題: | 《AJAX簡介》 |
網(wǎng)址: | http://www.blogjava.net/fanscial/archive/2005/08/31/11628.html | ||
作者: | Amour GUO | 標(biāo)題: | 《AJAX內(nèi)部交流文檔》 |
網(wǎng)址: | http://www.dragonson.com/doc/ajax.html | ||
作者: | MoztwWiki | 標(biāo)題: | 《AJAX上手篇》 |
網(wǎng)址: | http://wiki.moztw.org/index.php/AJAX_%E4%B8%8A%E6%89%8B%E7%AF%87 | ||
作者: | Philip McCarthy | 標(biāo)題: | 面向Java開發(fā)人員的Ajax:構(gòu)建動態(tài)的Java應(yīng)用程序 |
網(wǎng)址: | http://kb.csdn.net/java/Articles/200510/bed0423e-5297-49c9-9464-0e3eb733c8b5.html | ||
作者: | Philip McCarthy | 標(biāo)題: | 面向Java開發(fā)人員的Ajax:Ajax的Java對象序列化 |
網(wǎng)址: | http://kb.csdn.net/java/Articles/200510/a5b630cf-a2c2-46f1-8e3b-eadde723e734.html | ||
作者: | David Flanagan | 書名: | 《Javascript權(quán)威指南》 |