?? 面向 java 開發人員的 ajax ajax 的 java 對象序列化.htm
字號:
<name><c:out value="${item.name}" escapeXml="true"/></name>
<price>${item.formattedPrice}</price>
</item>
</c:forEach>
</items>
</order>
</c:forEach>
</orderhistory>
</PRE></TD></TR></TBODY></TABLE><BR>
<P>這個簡潔的模板只輸出訂單歷史視圖需要的數據,不輸出不相關的資料(例如商品說明)。創建產品搜索視圖的定制 XML
應當同樣簡單,這個視圖包含每個商品的完整說明和庫存水平。</P>
<P><A name=N10194><SPAN class=smalltitle>模板的問題</SPAN></A></P>
<P>另一方面,現在我需要為每個不同視圖創建一個新
JSP,而不能僅僅把需要的對象圖組織起來并序列化它。從設計的角度來說,許多人可能會有爭議,認為這無論如何是件好事,因為這意味著正式地考慮服務器要生成的文檔類型。而且,因為我現在要處理通用的模板環境,而不是特定于
XML 的 API,所以確保標記匹配、元素和屬性的順序正確以及 XML 實體(例如 <CODE><</CODE> 或
<CODE>&</CODE>)正確轉義就成了我的責任。JSP 的核心 <CODE>out</CODE>
標記使后面這項工作變得很容易,但是不是所有的模板技術都提供了這樣的機制。最后,沒有方便的途徑可以在服務器端根據方案檢驗生成的 XML
文檔的正確性,但這畢竟不是要在生產環境中做的事,可以方便地在開發期間處理它。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/c.gif" width=8
border=0></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD><IMG height=4 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/c.gif"
width="100%"><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/u_bold.gif"
width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#main"><B>回頁首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=N101A9><SPAN class=atitle>不用 XML 的響應數據</SPAN></A></P>
<P>迄今為止,我介紹的所有技術都用 XML 文檔的形式生成服務器響應。但是,XML 有一些問題。其中一個就是延遲。瀏覽器不能立即解析
XML 文檔并生成 DOM 模型,所以這會降低某些 Ajax
組件需要的“迅捷”感,特別是在較慢的機器上解析大型文檔的時候更是如此?!艾F場搜索”就是一個示例,在這種搜索中,當用戶輸入搜索術語時,就會從服務器提取搜索結果并顯示給用戶。對于現場搜索組件來說,迅速地響應輸入是非常重要的,但是同時它還需要迅速而持續地解析服務器的響應。</P>
<P>延遲是一個重要的考慮因素,但是避免使用 XML 的最大原因是差勁的客戶端 DOM API。清單 5
顯示了使用跨瀏覽器兼容的方式通過 DOM 得到某個值的時候,通常不得不面對的困難。</P><BR><BR><A
name=code5><B>清單 5. 在 JavaScript 中導航 XML 響應文檔</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
// Find name of first item in customer's 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;
</PRE></TD></TR></TBODY></TABLE><BR>
<P>當元素中間存在空白時,情況就變得更加復雜,因為每個元素的 <CODE>firstChild</CODE>
經常是個空白文本節點?,F在有 JavaScript 庫可以緩解處理 XML 文檔的麻煩。這些庫包括 Sarissa (請參閱 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#resources">參考資料</A>)和
Google-ajaXSLT,這兩個庫都把 XPath 功能添加到了大多數瀏覽器中。</P>
<P>但是,想想替代方案還是值得的。除了 <CODE>responseXML</CODE>
之外,<CODE>XMLHttpRequest</CODE> 對象還提供了名為 <CODE>responseText</CODE>
的屬性,這個屬性只是以字符串的方式提供服務器的響應體。</P>
<P><A name=N101D8><SPAN class=smalltitle>responseText
屬性</SPAN></A></P>
<P>當服務器需要向客戶機發送非常簡單的值時,<CODE>responseText</CODE> 特別方便,它可以避免 XML
導致的帶寬支出和處理支出。例如,簡單的 true/false
響應可以由服務器以純文本方式返回,可以是逗號分隔的簡單的名稱或數字列表。但是,一般來說,最好不要在同一個應用程序中把 XML
響應和純文本響應混合使用;保持單一數據格式可以讓代碼抽象和重用更加簡單。</P>
<P><CODE>responseText</CODE> 與 XML
響應數據結合時也會有用。在只需要從響應文檔中提取單一值的場景中,“欺騙性”地把 XML
當作文本字符串,而不把它當作結構化的文檔對待,會更方便。例如,清單 6
顯示了如何用正則表達式從顧客的訂單歷史中提取第一筆訂單的日期。不過,這實際是種花招,一般不應當依賴 XML
文檔的詞匯表達。</P><BR><BR><A name=code6><B>清單 6. 用正則表達式處理 XMLHttpRequest 的
responseText 對象</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
var orderHistoryText = req.responseText;
var matches = orderHistoryText.match(/<date>(.*?)<\/date>/);
var date = matches[1];
</PRE></TD></TR></TBODY></TABLE><BR>
<P>在某些情況下,采用即時方式使用 <CODE>responseText</CODE>
會比較方便。但是,理想情況下,應當有種途徑,可以用一種能夠讓 JavaScript 輕松導航、卻沒有 XML
處理支出的格式表示復雜的結構化數據。幸運的是,確實存在這樣一種格式。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/c.gif" width=8
border=0></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD><IMG height=4 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/c.gif"
width="100%"><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt=""
src="面向 Java 開發人員的 Ajax Ajax 的 Java 對象序列化.files/u_bold.gif"
width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#main"><B>回頁首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=N101FC><SPAN class=atitle>JavaScript 對象標注</SPAN></A></P>
<P>實際上,JavaScript 對象的大部分都由聯合數組、數字索引數組、字符串、數字或者這些類型的嵌套組合而成。因為所有類型都可以用
JavaScript 直接聲明,所以可以在一條語句中靜態地定義對象圖。清單 7 使用 JSON
語法聲明了一個對象,并演示了如何訪問這個對象。大括號表示聯合數組(即對象),它的鍵
-值組合由逗號分隔。方括號表示數字索引數組。</P><BR><BR><A name=code7><B>清單 7. 用 JSON 在
JavaScript 中直接聲明一個簡單對象</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
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 );
</PRE></TD></TR></TBODY></TABLE><BR>
<P>既然 JSON 是一個有趣的語言特性,那么它對 Ajax 有什么意義呢?妙處在于可以用 JSON 在 Ajax
服務器響應中通過網絡發送 JavaScript 對象圖。這意味著在客戶端可以避免使用笨拙的 DOM API 對 XML 進行導航 ——
只需要分析 JSON 響應,就會立即得到可以訪問的 JavaScript 對象圖。但是,首先需要把 JavaBean 變成
JSON。</P>
<P><A name=N10211><SPAN class=smalltitle>從 Java 類產生
JSON</SPAN></A></P>
<P>不同 XML 生成技術所具有的優缺點也適用于 JSON 的產生。而且可以證明,存在需要再次使用表示模板技術的情況。但是,使用
JSON 在理念上更接近于在應用層之間傳遞序列化的對象,而不是創建應用程序狀態的視圖。我將介紹如何用
<CODE>org.json</CODE> 這個 Java API 在 Java 類上創建
<CODE>toJSONObject()</CODE> 方法。然后,就可以把 <CODE>JSONObject</CODE>
簡單地序列化成 JSON。清單 8 反映了 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#code1">清單
1</A> 討論的 XML,顯示了 <CODE>Order</CODE> 類的 <CODE>toJSONObject()</CODE>
實現。</P><BR><BR><A name=code8><B>清單 8. Order 類的 toJSONObject()
方法實現</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
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<Item> iter =
items.iterator() ; iter.hasNext() ; ) {
jsonItems.put(iter.next().toJSONObject());
}
json.put("items",jsonItems);
return json;
}
</PRE></TD></TR></TBODY></TABLE><BR>
<P>可以看到,<CODE>org.json</CODE> API 非常簡單。 <CODE>JSONObject</CODE> 代表
JavaScript 對象(即聯
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -