扒开腿挺进岳湿润的花苞视频|将军边走边挺进她H树林|挺进朋友人妻张婉莹身体|岳脱得精光让我挺进去视频|第一次挺进莹莹的身体里视频|脱岳裙子从后面挺进去视频

新疆軟件開發(fā)

本站首頁 軟件開發(fā) 成功案例 公司新聞 公司簡介 客服中心 軟件技術(shù) 網(wǎng)站建設(shè)
  您現(xiàn)在的位置: 新疆二域軟件開發(fā)公司 >> Java技術(shù) >> 文章正文

使用Ajax時(shí)Java對(duì)象的序列化


多數(shù) Java 開發(fā)人員已經(jīng)把模型-視圖-控制器(MVC)模式應(yīng)用在他們的 Web 應(yīng)用程序上。在傳統(tǒng)的 Web 應(yīng)用程序中,視圖組件由 JSP 或者其他表示技術(shù)(例如 Velocity 模板)構(gòu)成。

這些表示組件動(dòng)態(tài)地生成全新的 HTML 頁面,替代用戶以前正在查看的頁面,從而更新用戶界面。但是,在 Java Web 應(yīng)用程序使用 Ajax UI 的情況下,基于從 XMLHttpRequest 的響應(yīng)接收到的數(shù)據(jù),JavaScript 客戶端代碼對(duì)于更新用戶看到的內(nèi)容負(fù)有最終責(zé)任。從服務(wù)器的角度來看,視圖成為它響應(yīng)客戶機(jī)請(qǐng)求而發(fā)送的數(shù)據(jù)表示。

本文側(cè)重于可以用來生成 Java 對(duì)象以數(shù)據(jù)為中心的視圖的技術(shù)。我將演示可以把 JavaBeans 變成 XML 文檔的各種方法,并且討論每種方法的優(yōu)劣。您將看到為什么 XML 并不總是最好的途徑:對(duì)于簡單的 Ajax 請(qǐng)求來說,傳輸純文本更好。

最后,我還將介紹 JavaScript 對(duì)象標(biāo)注(JSON)。JSON 允許數(shù)據(jù)以序列化的 JavaScript 對(duì)象圖的形式傳輸,在客戶端代碼中處理序列化的 JavaScript 對(duì)象圖極為容易。

關(guān)于示例

我將使用一個(gè)示例應(yīng)用程序和幾個(gè)用例來演示這里討論的技術(shù)特性和技術(shù)。圖 1 顯示的極為簡單的數(shù)據(jù)模型可以表示示例用例。這個(gè)模型代表在線商店中的顧客帳戶。顧客擁有以前訂單的集合,每個(gè)訂單包含幾個(gè)商品。

 

雖然 XMLHttpRequest 對(duì)于發(fā)送數(shù)據(jù)使用的格式?jīng)]有做任何限制,但是對(duì)于多數(shù)目的來說,只發(fā)送傳統(tǒng)的表單數(shù)據(jù)是適合的,所以我的討論集中在服務(wù)器的響應(yīng)上。

響應(yīng)也可以有基于文本的格式,但是正如它的名字表示的,XMLHttpRequest 具有內(nèi)置的處理 XML 響應(yīng)數(shù)據(jù)的能力。這使 XML 成為 Ajax 響應(yīng)的默認(rèn)選擇,所以我們從 XML 格式開始討論。

從 Java 類產(chǎn)生 XML

把 Ajax 響應(yīng)作為 XML 來傳遞有許多原因:每個(gè)支持 Ajax 的瀏覽器都有導(dǎo)航 XML 文檔的方法,也有許多服務(wù)器端技術(shù)可以處理 XML 數(shù)據(jù)。

通過制定一個(gè)方案,描述要交換的文檔類型,在 Ajax 客戶端和服務(wù)器端之間很容易定義合約,而且如果服務(wù)器端架構(gòu)采用面向服務(wù)的方式,那么使用 XML 也可以允許非 Ajax 客戶機(jī)使用您提供的數(shù)據(jù)。

我將考慮從 Java 對(duì)象產(chǎn)生 XML 數(shù)據(jù)的三種方法,并討論每種方法的優(yōu)劣。

自行進(jìn)行序列化

首先,可以從對(duì)象圖以編程的方式生成 XML。這種方式可以簡單到只是在每個(gè) JavaBean 類中實(shí)現(xiàn) toXml() 方法即可。然后就可以選擇合適的 XML API,讓每個(gè) bean 提供表示自己狀態(tài)的元素,并遞歸地對(duì)自己的成員調(diào)用對(duì)象圖。

顯然,這種方式無法擴(kuò)展到大量的類,因?yàn)槊總(gè)類都需要專門編寫自己的 XML 生成代碼。從好的方面來看,這是一個(gè)實(shí)現(xiàn)起來簡單的方式,沒有額外的配置支出或者更復(fù)雜的構(gòu)建過程支出,任何 JavaBean 圖都可以只用幾個(gè)調(diào)用就變成 XML 文檔。

我曾把XML標(biāo)記字符串連接在一起,實(shí)現(xiàn)了toXml()方法。上次我就提到過,這是個(gè)糟糕的方法,因?yàn)樗汛_保標(biāo)記配對(duì)、實(shí)體編碼等工作的負(fù)擔(dān)放在每個(gè) toXml() 方法的代碼中。

在 Java 平臺(tái)上有幾個(gè) XML API 可以替您做這些工作,這樣您就可以把精力集中在 XML 的內(nèi)容上。清單 1 用 JDOM API 實(shí)現(xiàn)了在線商店示例中表示訂單的類中的 toXml()(請(qǐng)參閱 圖 1)。

清單 1. Order 類的 toXml() 的 JDOM 實(shí)現(xiàn)


public Element toXml()
{

Element elOrder = new Element("order");
elOrder.setAttribute("id",id);

elOrder.setAttribute
("cost",getFormattedCost());

Element elDate =
new Element("date").addContent(date);
elOrder.addContent(elDate);

Element elItems = new Element("items");
for (Iterator iter =
items.iterator() ; iter.hasNext() ; )
{
elItems.addContent(iter.next().toXml());
}
elOrder.addContent(elItems);

return elOrder;
}

 


在這里可以看到用 JDOM 創(chuàng)建元素、使用屬性和添加元素內(nèi)容有多么簡單。遞歸地調(diào)用復(fù)合 JavaBean 的 toXml() 方法是為了取得它們子圖的 Element 表示。例如,items 元素的內(nèi)容是通過調(diào)用 Order 聚合的每個(gè) Item 對(duì)象上的 toXml() 得到的。

一旦所有的 JavaBean 都實(shí)現(xiàn)了 toXml() 方法,那么把任意對(duì)象圖序列化成 XML 文檔并返回給 Ajax 客戶機(jī)就簡單了,如清單 2 所示。

清單 2. 從 JDOM 元素生成 XML 響應(yīng)


public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws java.io.IOException,
ServletException
{

String custId =
req.getParameter("username");
Customer customer =
getCustomer(custId);

Element responseElem =
customer.toXml();
Document responseDoc =
new Document(responseElem);

res.setContentType("application/xml");
new XMLOutputter().output
(responseDoc,res.getWriter());
}

 


JDOM 再次把工作變得非常簡單。只需要在對(duì)象圖返回的 XML 元素外面包裝一個(gè) Document,然后用 XMLOutputter 把文檔寫入 servlet 響應(yīng)即可。清單 3 顯示了用這種方式生成的 XML 示例,用 JDOM Format.getPrettyFormat() 對(duì) XMLOutputter進(jìn)行初始化,格式化得非常好。在這個(gè)示例中,顧客只做了一個(gè)訂單,包含兩個(gè)商品。

清單 3. 代表顧客的 XML 文檔


encoding="UTF-8"?>

James Hyrax

cost="$349.98">
08-26-2005


Oolong 512MB
CF Card
512 Megabyte Type 1
CompactFlash card.
Manufactured by Oolong
Industries$49.99


Fujak Superpix72 Camera
7.2 Megapixel digital
camera featuring six
shooting modes and 3x
optical zoom. Silver.$299.99

 

 

 

自行序列化的不足

有趣的是,清單 3 中的代碼展示了讓 JavaBean 把自己序列化為 XML 的一個(gè)主要不足。假設(shè)要用這個(gè)文檔表示顧客的訂單歷史視圖。在這種情況下,不太可能要顯示每個(gè)歷史訂單中每個(gè)商品的完整說明,或者告訴顧客他或她自己的姓名。

但是如果應(yīng)用程序有一個(gè) ProductSearch 類,它就是以 Item bean 列表的形式返回搜索結(jié)果,那么在 Item 的 XML 表示中包含說明可能會(huì)有幫助。

而且,Item 類上代表當(dāng)前庫存水平的額外字段,在產(chǎn)品搜索視圖中可能就是需要顯示的有用信息。但是,不管當(dāng)前的庫存水平是否與當(dāng)前情況相關(guān)(比如對(duì)顧客的訂單歷史來說),這個(gè)字段都會(huì)從包含 Item 的任何對(duì)象圖中序列化出來。

從設(shè)計(jì)的角度來看,這是數(shù)據(jù)模型與視圖生成耦合的經(jīng)典問題。每個(gè) bean 只能用一種途徑序列化自己,一成不變的方式意味著 Ajax 交互最終要交換它們不需要交換的數(shù)據(jù),因此造成客戶端代碼要從文檔中找到需要的信息更加困難,而且也會(huì)增加帶寬消耗和客戶端的 XML 解析時(shí)間。

這種耦合的另一個(gè)后果就是 XML 的語法不能脫離 Java 類獨(dú)立變化。例如,對(duì)顧客文檔的方案做修改,可能會(huì)影響多個(gè) Java 類,造成它們也不得不做修改和重新編譯。

我稍后會(huì)解決這些問題,但是首先來看一個(gè)對(duì)自行序列化方式的可伸縮性問題的解決方案:XML 綁定框架。

XML 綁定框架

近些年來,已經(jīng)開發(fā)了多個(gè) Java API 來簡化 XML 文檔到 Java 對(duì)象圖的綁定過程。多數(shù)都提供了 XML 編排和拆解;也就是說,它們可以在 Java 對(duì)象圖和 XML 之間執(zhí)行雙向會(huì)話。

這些框架封裝了 XML 處理的全部工作,這意味著應(yīng)用程序代碼只需要處理普通的 Java 類。它們還希望提供有用的輔助功能,例如文檔驗(yàn)證;\統(tǒng)來說,這些框架采用了兩種不同的方式:代碼生成和對(duì)象到 XML 映射。我將分別解釋這兩種方式。

代碼生成方式

使用代碼生成的框架包括 XMLBeans、JAXB、Zeus 和 JBind。Castor 也能使用這項(xiàng)技術(shù)。這類框架的起點(diǎn)是描述文檔數(shù)據(jù)類型的 XML 方案。使用框架提供的工具,就可以生成代表這些方案定義類型的 Java 類。最后,用這些生成的類編寫應(yīng)用程序,表示自己的模型數(shù)據(jù),并通過框架提供的一些輔助機(jī)制把數(shù)據(jù)序列化成 XML。

如果應(yīng)用程序要使用大型 XML 語法,那么代碼生成方式是個(gè)很好的方法。在數(shù)十個(gè)類上編寫定制 XML 序列化代碼的可伸縮性問題由此消除。另一方面,也不再需要定義自己的 JavaBean。

框架生成的 Java 類通常非常符合 XML 的結(jié)構(gòu),所以對(duì)它們進(jìn)行編碼很難。而且,生成的類變成啞數(shù)據(jù)容器,因?yàn)橐话悴荒芟蛩鼈兲砑有袨椤?

一般來說,在應(yīng)用程序代碼中要做些妥協(xié),才能很好地處理方案生成的類型。另一個(gè)缺陷是如果修改方案,會(huì)造成生成的類也要修改,所以也就會(huì)對(duì)圍繞它們編寫的代碼帶來相應(yīng)的影響。

這種類型的 XML 綁定框架在數(shù)據(jù)拆解時(shí)最有用(例如,使用 XML 文檔并把它們轉(zhuǎn)化成 Java 對(duì)象)。除非擁有大型數(shù)據(jù)模型而且有可能從生成的類中獲益,否則基于代碼生成的框架對(duì)于 Ajax 應(yīng)用程序來說可能有很大的殺傷力。

映射方式

采用映射方式的框架包括 Castor 和 Apache Commons Betwixt。映射通常是比代碼生成更靈活和更輕量的解決方案。首先,可以像通常一樣編寫 JavaBean,包括任何行為以及任何自己喜歡的方便的方法。

然后,在運(yùn)行時(shí),調(diào)用框架中基于內(nèi)省的編排器,并根據(jù)對(duì)象成員的類型、名稱和值生成 XML 文檔。通過定義類的映射文件,可以覆蓋默認(rèn)的綁定策略,并就類在 XML 中的表示方式對(duì)編排器提出建議。

這種方法是在可伸縮性與靈活性之間的良好折中?梢园凑兆约合矚g的方式編寫 Java 類,編排器負(fù)責(zé)處理 XML。雖然映射定義文件編寫起來簡單,可伸縮性也足夠好,但是映射規(guī)則最多只能改變標(biāo)準(zhǔn)的綁定行為,而且在對(duì)象結(jié)構(gòu)和它們的 XML 表示之間總要?dú)埩粢恍詈。最終,可能不得不在 Java 表示或 XML 格式之間任選一個(gè)做些折中,才能讓映射方法起作用。

數(shù)據(jù)綁定總結(jié)

Dennis Sosnoski 就 XML 數(shù)據(jù)綁定 API 的主題,在代碼生成和代碼映射兩個(gè)方面寫了深入的文章。如果想進(jìn)一步研究這個(gè)領(lǐng)域,我推薦他在 Castor 和代碼生成框架方面的精彩文章。

總之,代碼生成方式損失了過多的靈活性和方便性,對(duì)于典型的 Ajax 應(yīng)用程序用處不大。另一方面,基于映射的框架可能工作得很好,但是要恰到好處地調(diào)整它們的映射策略,以便從對(duì)象生成需要的 XML。

所有的 XML 綁定 API 都具有手工序列化技術(shù)的一個(gè)主要不足:模型和視圖的耦合。被限制為一個(gè)類型一個(gè) XML 表示,就意味著在網(wǎng)絡(luò)上總要有冗余數(shù)據(jù)傳輸。

更嚴(yán)重的問題是,在情況要求客戶端代碼使用專門視圖時(shí),客戶端代碼卻無法得到它,所以可能要費(fèi)力地處理給定對(duì)象圖的一成不變的視圖。

在傳統(tǒng)的 Web 應(yīng)用程序開發(fā)中,采用頁面模板系統(tǒng)把視圖生成與控制器邏輯和模型數(shù)據(jù)干凈地分離。這種方法在 Ajax 場(chǎng)景中也會(huì)有幫助。

頁面模板系統(tǒng)

任何通用目的的頁面模板技術(shù)都可以用來生成 XML,從而使 Ajax 應(yīng)用程序根據(jù)自己的數(shù)據(jù)模型生成任何 XML 響應(yīng)文檔。

額外收獲是:模板可以用簡單的、表現(xiàn)力強(qiáng)的標(biāo)記語言編寫,而不是用一行行的 Java 代碼編寫。清單 5 是一個(gè) JSP 頁面,采用了 Customer bean 并表示出定制的 XML 視圖,適合客戶端代碼生成訂單歷史組件。

清單 4. 生成訂單歷史文檔的 JSP

 

 

value="${requestScope.customer}"/>

"${cust.username}">
"${cust.orders}">
"${order.formattedCost}">
${order.date}

"${order.items}">

escapeXml="true"/>${item.formattedPrice}

 

 

 

 


這個(gè)簡潔的模板只輸出訂單歷史視圖需要的數(shù)據(jù),不輸出不相關(guān)的資料(例如商品說明)。創(chuàng)建產(chǎn)品搜索視圖的定制 XML 應(yīng)當(dāng)同樣簡單,這個(gè)視圖包含每個(gè)商品的完整說明和庫存水平。

模板的問題

另一方面,現(xiàn)在我需要為每個(gè)不同視圖創(chuàng)建一個(gè)新 JSP,而不能僅僅把需要的對(duì)象圖組織起來并序列化它。從設(shè)計(jì)的角度來說,許多人可能會(huì)有爭議,認(rèn)為這無論如何是件好事,因?yàn)檫@意味著正式地考慮服務(wù)器要生成的文檔類型。而且,因?yàn)槲椰F(xiàn)在要處理通用的模板環(huán)境,而不是特定于 XML 的 API,所以確保標(biāo)記匹配、元素和屬性的順序正確以及 XML 實(shí)體(例如 < 或 &)正確轉(zhuǎn)義就成了我的責(zé)任。

JSP 的核心 out 標(biāo)記使后面這項(xiàng)工作變得很容易,但是不是所有的模板技術(shù)都提供了這樣的機(jī)制。最后,沒有方便的途徑可以在服務(wù)器端根據(jù)方案檢驗(yàn)生成的 XML 文檔的正確性,但這畢竟不是要在生產(chǎn)環(huán)境中做的事,可以方便地在開發(fā)期間處理它。

不用 XML 的響應(yīng)數(shù)據(jù)

迄今為止,我介紹的所有技術(shù)都用 XML 文檔的形式生成服務(wù)器響應(yīng)。但是,XML 有一些問題。其中一個(gè)就是延遲。瀏覽器不能立即解析 XML 文檔并生成 DOM 模型,所以這會(huì)降低某些 Ajax 組件需要的“迅捷”感,特別是在較慢的機(jī)器上解析大型文檔的時(shí)候更是如此。

“現(xiàn)場(chǎng)搜索”就是一個(gè)示例,在這種搜索中,當(dāng)用戶輸入搜索術(shù)語時(shí),就會(huì)從服務(wù)器提取搜索結(jié)果并顯示給用戶。對(duì)于現(xiàn)場(chǎng)搜索組件來說,迅速地響應(yīng)輸入是非常重要的,但是同時(shí)它還需要迅速而持續(xù)地解析服務(wù)器的響應(yīng)。

延遲是一個(gè)重要的考慮因素,但是避免使用 XML 的最大原因是差勁的客戶端 DOM API。清單 5 顯示了使用跨瀏覽器兼容的方式通過 DOM 得到某個(gè)值的時(shí)候,通常不得不面對(duì)的困難。

清單 5. 在 JavaScript 中導(dǎo)航 XML 響應(yīng)文檔


// Find name of first item
in customers last order
var orderHistoryDoc = req.responseXML;

var orders =
orderHistoryDoc.getElementsByTagName("order");
var lastOrder =
orders[orders.length - 1];

var firstItem =
lastOrder.getElementsByTagName("item")[0];
var itemNameElement =
firstItem.firstChild;

var itemNameText =
itemNameElement.firstChild.data;

 


當(dāng)元素中間存在空白時(shí),情況就變得更加復(fù)雜,因?yàn)槊總(gè)元素的 firstChild 經(jīng)常是個(gè)空白文本節(jié)點(diǎn)。

現(xiàn)在有 JavaScript 庫可以緩解處理 XML 文檔的麻煩。這些庫包括 Sarissa 和 Google-ajaXSLT,這兩個(gè)庫都把 XPath 功能添加到了大多數(shù)瀏覽器中。

但是,想想替代方案還是值得的。除了 responseXML 之外,XMLHttpRequest 對(duì)象還提供了名為 responseText 的屬性,這個(gè)屬性只是以字符串的方式提供服務(wù)器的響應(yīng)體。

responseText 屬性

當(dāng)服務(wù)器需要向客戶機(jī)發(fā)送非常簡單的值時(shí),responseText 特別方便,它可以避免 XML 導(dǎo)致的帶寬支出和處理支出。例如,簡單的 true/false 響應(yīng)可以由服務(wù)器以純文本方式返回,可以是逗號(hào)分隔的簡單的名稱或數(shù)字列表。

但是,一般來說,最好不要在同一個(gè)應(yīng)用程序中把 XML 響應(yīng)和純文本響應(yīng)混合使用;保持單一數(shù)據(jù)格式可以讓代碼抽象和重用更加簡單。

responseText 與 XML 響應(yīng)數(shù)據(jù)結(jié)合時(shí)也會(huì)有用。在只需要從響應(yīng)文檔中提取單一值的場(chǎng)景中,“欺騙性”地把 XML 當(dāng)作文本字符串,而不把它當(dāng)作結(jié)構(gòu)化的文檔對(duì)待,會(huì)更方便。

例如,清單 6 顯示了如何用正則表達(dá)式從顧客的訂單歷史中提取第一筆訂單的日期。不過,這實(shí)際是種花招,一般不應(yīng)當(dāng)依賴 XML 文檔的詞匯表達(dá)。

清單 6. 用正則表達(dá)式處理 XMLHttpRequest 的 responseText 對(duì)象


var orderHistoryText =
req.responseText;
var matches =
orderHistoryText.match
(/(.*?)<\/date>/);

var date = matches[1];

 


在某些情況下,采用即時(shí)方式使用 responseText 會(huì)比較方便。但是,理想情況下,應(yīng)當(dāng)有種途徑,可以用一種能夠讓 JavaScript 輕松導(dǎo)航、卻沒有 XML 處理支出的格式表示復(fù)雜的結(jié)構(gòu)化數(shù)據(jù)。幸運(yùn)的是,確實(shí)存在這樣一種格式。
JavaScript 對(duì)象標(biāo)注

實(shí)際上,JavaScript 對(duì)象的大部分都由聯(lián)合數(shù)組、數(shù)字索引數(shù)組、字符串、數(shù)字或者這些類型的嵌套組合而成。因?yàn)樗蓄愋投伎梢杂?JavaScript 直接聲明,所以可以在一條語句中靜態(tài)地定義對(duì)象圖。

清單 7 使用 JSON 語法聲明了一個(gè)對(duì)象,并演示了如何訪問這個(gè)對(duì)象。大括號(hào)表示聯(lián)合數(shù)組(即對(duì)象),它的鍵 -值組合由逗號(hào)分隔。方括號(hào)表示數(shù)字索引數(shù)組。

清單 7. 用 JSON 在 JavaScript 中直接聲明一個(gè)簡單對(duì)象


var band =
{
name: "The Beatles",
members: [
{
name: "John",
instruments:
["Vocals","Guitar","Piano"]
},
{
name: "Paul",
instruments:
["Vocals","Bass","Piano","Guitar"]
},
{
name: "George",
instruments:
["Guitar","Vocals"]
},
{
name: "Ringo",
instruments:
["Drums","Vocals"]
}
]
};

// Interrogate the band object
var musician = band.members[3];
alert( musician.name
+ " played " +
musician.instruments[0]
+ " with " +
band.name );

 


既然 JSON 是一個(gè)有趣的語言特性,那么它對(duì) Ajax 有什么意義呢?妙處在于可以用 JSON 在 Ajax 服務(wù)器響應(yīng)中通過網(wǎng)絡(luò)發(fā)送 JavaScript 對(duì)象圖。

這意味著在客戶端可以避免使用笨拙的 DOM API 對(duì) XML 進(jìn)行導(dǎo)航 —— 只需要分析 JSON 響應(yīng),就會(huì)立即得到可以訪問的 JavaScript 對(duì)象圖。但是,首先需要把 JavaBean 變成 JSON。

從 Java 類產(chǎn)生 JSON

不同 XML 生成技術(shù)所具有的優(yōu)缺點(diǎn)也適用于 JSON 的產(chǎn)生。而且可以證明,存在需要再次使用表示模板技術(shù)的情況。但是,使用 JSON 在理念上更接近于在應(yīng)用層之間傳遞序列化的對(duì)象,而不是創(chuàng)建應(yīng)用程序狀態(tài)的視圖。

我將介紹如何用 org.json 這個(gè) Java API 在 Java 類上創(chuàng)建 toJSONObject() 方法。然后,就可以把 JSONObject 簡單地序列化成 JSON。清單 8 反映了 清單 1 討論的 XML,顯示了 Order 類的 toJSONObject() 實(shí)現(xiàn)。

清單 8. Order 類的 toJSONObject() 方法實(shí)現(xiàn)


public JSONObject toJSONObject()
{

JSONObject json = new JSONObject();
json.put("id",id);
json.put("cost",getFormattedCost());
json.put("date",date);

JSONArray jsonItems = new JSONArray();
for (Iterator iter =
items.iterator() ; iter.hasNext() ; )
{
jsonItems.put(iter.next().toJSONObject());
}
json.put("items",jsonItems);

return json;
}

 


可以看到,org.json API 非常簡單。 JSONObject 代表 JavaScript 對(duì)象(即聯(lián)合數(shù)組),有不同的 put() 方法,方法接受的 String 鍵和值是原生類型、String 類型或其他 JSON 類型。
JSONArray 代表索引數(shù)組,所以它的 put() 方法只接受一個(gè)值。請(qǐng)注意在清單 8 中,創(chuàng)建 jsonItems 數(shù)組,然后再用 put() 把它附加到 json 對(duì)象上;可以用另外一種方法做這項(xiàng)工作,就是對(duì)每個(gè)項(xiàng)目調(diào)用:

 

 

 


json.accumulate("items",
iter.next().toJSONObject());

 


accumulate() 方法與 put()類似,區(qū)別在于它把值添加到按照鍵進(jìn)行識(shí)別的索引數(shù)組。清單 9 顯示了如何序列化 JSONObject 并把它寫入 servlet 響應(yīng)。

清單 9. 從 JSONObject 生成序列化的 JSON 響應(yīng)


public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws java.io.IOException,
ServletException
{

String custId =
req.getParameter("username");
Customer customer =
getCustomer(custId);

res.setContentType("application/x-json");
res.getWriter().print
(customer.toJSONObject());
}

 


可以看到,它實(shí)際上什么也沒有做。在這里隱式調(diào)用的 JSONObject 的 toString() 方法做了所有工作。請(qǐng)注意,application/x-json 內(nèi)容類型還有一點(diǎn)不確定 —— 在編寫這篇文章的時(shí)候,關(guān)于 JSON 應(yīng)當(dāng)屬于什么 MIME 類型還沒有定論。但是,目前 application/x-json 是合理的選擇。清單 10 顯示了這個(gè) servlet 代碼的示例響應(yīng)。

清單 10. Customer bean 的 JSON 表示


{
"orders":
[
{
"items":
[
{
"price": "$49.99",
"description": "
512 Megabyte Type 1 CompactFlash card.
Manufactured by Oolong Industries",
"name": "Oolong 512MB CF Card",
"id": "i-55768"
},
{
"price": "$299.99",
"description": "
7.2 Megapixel digital camera featuring six
shooting modes and 3x optical zoom. Silver.",
"name": "Fujak Superpix72 Camera",
"id": "i-74491"
}
],
"date": "08-26-2005",
"cost": "$349.98",
"id": "o-11123"
}
],
"realname": "James Hyrax",
"username": "jimmy66"
}

 


在客戶端使用 JSON

處理的最后一步是把在客戶端把 JSON 數(shù)據(jù)變成 JavaScript 對(duì)象。這可以通過對(duì) eval() 的簡單調(diào)用實(shí)現(xiàn),這個(gè)函數(shù)可以即時(shí)地解釋包含 JavaScript 表達(dá)式的字符串。

清單 11 把 JSON 響應(yīng)轉(zhuǎn)變成 JavaScript 對(duì)象圖,然后執(zhí)行清單 5 的任務(wù),從顧客的最后一次訂單中得到第一個(gè)商品的名稱。

清單 11. 評(píng)估 JSON 響應(yīng)


var jsonExpression =
"(" + req.responseText + ")";
var customer = eval(jsonExpression);

// Find name of first
item in customers last order
var lastOrder = customer.orders
[customer.orders.length-1];
var name = lastOrder.items[0].name;

 


比較清單 11 和 清單 5 可以發(fā)現(xiàn)使用 JSON 的客戶端的優(yōu)勢(shì)。如果在 Ajax 項(xiàng)目中要在客戶端對(duì)許多復(fù)雜的服務(wù)器響應(yīng)進(jìn)行導(dǎo)航,那么 JSON 可能適合您的需要。

JSON 和 XMLHttpRequest 結(jié)合還會(huì)讓 Ajax 交互看起來更像 RPC 調(diào)用而不是 SOA 請(qǐng)求,這對(duì)應(yīng)用程序的設(shè)計(jì)可能會(huì)有意義。在下一篇文章中,我要研究的框架,就是明確地為了讓 JavaScript 代碼對(duì)服務(wù)器端對(duì)象進(jìn)行遠(yuǎn)程方法調(diào)用而設(shè)計(jì)的。
JSON 的不足

JSON 也有它的不足。使用這里介紹的 JSON 方式,就沒有辦法針對(duì)每個(gè)請(qǐng)求對(duì)對(duì)象的序列化進(jìn)行裁剪,所以不需要的字段可能經(jīng)常會(huì)在網(wǎng)絡(luò)上發(fā)送。

另外,添加 toJSONObject() 方法到每個(gè) JavaBean,可伸縮性不太好,雖然用內(nèi)省和標(biāo)注編寫一個(gè)通用的 JavaBean 到 JSON 的序列化器可能很簡單。最后,如果服務(wù)器端代碼是面向服務(wù)的,沒有單獨(dú)針對(duì)處理 Ajax 客戶請(qǐng)求調(diào)整過,那么由于對(duì) XML 一致的支持,XML 會(huì)是更好的選擇。

比較序列化技術(shù)

現(xiàn)在已經(jīng)看到了把 Java 狀態(tài)傳輸?shù)?Ajax 客戶端的五種不同技術(shù)。我討論了自行手工編碼 XML 序列化、通過代碼生成的 XML 綁定、通過映射機(jī)制的 XML 綁定、基于模板的 XML 生成以及手工編碼到 JSON 的序列化。

每種技術(shù)都有自己的優(yōu)勢(shì)和不足,分別適用于不同的應(yīng)用程序架構(gòu)。為了總結(jié)每種方式的優(yōu)勢(shì)與不足,表 1 從六個(gè)方面進(jìn)行了粗略的評(píng)分:

可伸縮性

描述技術(shù)適應(yīng)大量數(shù)據(jù)類型的容易程度。對(duì)于每個(gè)附加類型,編碼和配置工作量是否會(huì)增長?

易于集成

評(píng)估把技術(shù)集成到項(xiàng)目的簡單程度。是否需要更加復(fù)雜的構(gòu)建過程?是否增加了部署的復(fù)雜性?

Java 類 API

描述以指定方式處理服務(wù)器端 Java 對(duì)象的容易程度。是可以編寫普通的 bean,還是不得不處理笨拙的文檔表示?

對(duì)輸出的控制

描述對(duì)類的序列化表示控制的精確程度。

視圖靈活性

評(píng)估從同一組對(duì)象是否可以創(chuàng)建不同的、定制的數(shù)據(jù)序列化。

客戶端數(shù)據(jù)訪問

描述 JavaScript 代碼處理服務(wù)器響應(yīng)數(shù)據(jù)的難易程度。


結(jié)束語

表 1 中的數(shù)據(jù)并不表明某項(xiàng)序列化技術(shù)比其他的技術(shù)好。畢竟,六種標(biāo)準(zhǔn)的相對(duì)重要性取決于項(xiàng)目的具體情況。例如,如果要處理數(shù)百種數(shù)據(jù)類型,這時(shí)想要的是可伸縮性,那么代碼生成可能就是最好的選擇。

如果需要為同一數(shù)據(jù)模型生成多個(gè)不同視圖,那么就應(yīng)當(dāng)使用頁面模板。如果處理的是小規(guī)模項(xiàng)目,想降低需要編寫的JavaScript代碼數(shù)量,那么請(qǐng)考慮JSON。希望這篇文章為您提供了選擇適合自己應(yīng)用程序的序列化技術(shù)所需要的信息。

 

作者:baocl | 文章來源:塞迪網(wǎng) | 更新時(shí)間:2007-11-6 11:12:56

  • 上一篇文章:

  • 下一篇文章:

  • 相關(guān)文章:
    JAVA開發(fā)的6個(gè)實(shí)踐的例子
    JAVA中的抽象類型的一些概念
    java語言開發(fā)程序中的幾個(gè)例子大家看看
    了解java開發(fā)語言在軟件開發(fā)中的幾個(gè)誤區(qū)
    如何才能使用Java實(shí)現(xiàn)內(nèi)部領(lǐng)域的特定語言
    Java開發(fā)學(xué)習(xí)小心使用Date以及Time類
    sun最近修補(bǔ)了一部分java的安全補(bǔ)丁
    Java程序員應(yīng)該了解那些開源協(xié)議
    java性能優(yōu)化的一些見解
    解析c#語言和java語言最相似的地方
    軟件技術(shù)
    · 開發(fā)語言
    · Java技術(shù)
    · .Net技術(shù)
    · 數(shù)據(jù)庫開發(fā)
    最新文章  
    ·j2se 嵌入式腳本抓取引擎
    ·JAVA開發(fā)的6個(gè)實(shí)踐的例子
    ·JBuilder7 / Weblogic7開發(fā)
    ·JAVA中的抽象類型的一些概
    ·java語言開發(fā)程序中的幾個(gè)
    ·了解java開發(fā)語言在軟件開
    ·如何才能使用Java實(shí)現(xiàn)內(nèi)部
    ·Java開發(fā)學(xué)習(xí)小心使用Date
    ·Java程序員應(yīng)該了解那些開
    ·java性能優(yōu)化的一些見解
    ·介紹JDK5.0一些collection
    ·基礎(chǔ)學(xué)習(xí):java中使用存儲(chǔ)
    ·解析c#語言和java語言最相
    ·Java語言學(xué)習(xí):jAVA中 的多
    ·Java是不是應(yīng)該增加新特性
    關(guān)于我們 | 軟件開發(fā) | 下載試用 | 客服中心 | 聯(lián)系我們 | 友情鏈接 | 網(wǎng)站地圖 | 新疆電子地圖 | RSS訂閱
    版權(quán)所有 © 2016 新疆二域軟件開發(fā)網(wǎng) m.jdtbank.com All Rights Reserved 新ICP備14003571號(hào)
    新疆軟件開發(fā)總機(jī):0991-4842803、4811639.
    客服QQ:596589785 ;地址:新疆烏魯木齊北京中路華聯(lián)大廈A-5C 郵編:830000
     
    肃南| 普安县| 通许县| 温州市| 东安县| 洮南市| 西城区| 留坝县| 伊金霍洛旗| 礼泉县| 文安县| 浦城县| 郸城县| 柘城县| 长岛县| 东明县| 昆明市| 泽库县| 宁夏| 阜宁县| 萨迦县| 新平| 共和县| 龙州县| 绵竹市| 柳江县| 蒙阴县| 高淳县| 祥云县| 林州市| 抚远县| 定兴县| 商洛市| 英德市| 仙游县| 华安县| 清丰县| 远安县| 巴彦淖尔市| 双鸭山市| 大方县|