Michael Chen's Blog

          World in my view is a word of my view
          posts - 2, comments - 4, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          QuirksBlog: The AJAX response: XML, HTML, or JSON?

          早先這篇文章在TSS上貼出的時候,我很快的瀏覽,便一眼看出這篇文章作者所處的角度。事實上,AJAX概念的不完整和不嚴(yán)密性——異步的JavaScript + XML——導(dǎo)致作者將AJAX的輸出分為三種類型:XML, HTML片斷和JSON對象字符串。

          首先看XML。對于RPC的數(shù)據(jù)傳輸,XML從來都是當(dāng)仁不二的選擇。對于將對象序列化為XML字符串的方式,往往有兩種選擇,一種是將對象本身的屬性作為節(jié)點進(jìn)行輸出,一種是利用語言的元數(shù)據(jù)特性進(jìn)行序列化輸出。兩者存在較大不同。對于第一種,輸出案例如下:

          <books>
              
          <book>
                  
          <title>JavaScript, the Definitive Guide</title>
                  
          <publisher>O'Reilly</publisher>
                  
          <author>David Flanagan</author>
                  
          <cover src="/images/cover_defguide.jpg" />
                  
          <blurb>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</blurb>
              
          </book>
              
          <book>
                  
          <title>DOM Scripting</title>
                  
          <publisher>Friends of Ed</publisher>
                  
          <author>Jeremy Keith</author>
                  
          <cover src="/images/cover_domscripting.jpg" />
                  
          <blurb>Praesent et diam a ligula facilisis venenatis.</blurb>
              
          </book>
          </books>


          而對于第二種,輸出案例如下:

          <list>
              
          <type>java.util.List</type>
              
          <map>
                  
          <type>yourapp.domain.Book</type>
                  
          <string>title</string>
                  
          <string>JavaScript, the Definitive Guide</string>
                  
          <string>publisher</string>
                  
          <string>O'Reilly</string>
                  
          <string>author</string>
                  
          <string>David Flanagan</string>
                  
          <string>cover</string>
                  
          <string>/images/cover_defguide.jpg</string>
                  
          <string>blurb</string>
                  
          <string>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</string>

              
          </map>
              
          <map>
                  
          <type>yourapp.domain.Book</type>
                  
          <string>title</string>
                  
          <string>DOM Scripting</string>
                  
          <string>publisher</string>
                  
          <string>Friends of Ed</string>
                  
          <string>author</string>
                  
          <string>Jeremy Keith</string>
                  
          <string>cover</string>
                  
          <string>/images/cover_domscripting.jpg</string>
                  
          <string>blurb</string>
                  
          <string>Praesent et diam a ligula facilisis venenatis.</string>

              
          </map>
          </list>


          前一種一般來說是同一進(jìn)程內(nèi)(同一JVM內(nèi))對對象進(jìn)行序列化和反序列化的方法,在XML-Java綁定一類的框架中比較多見,例如XStream, JiBX, Castor等等。當(dāng)同一進(jìn)程內(nèi)能夠找到對象具備的正確類型時,這種序列化/反序列化設(shè)計和實現(xiàn)都不太困難,而且針對空值處理也比較容易。

          可以看出,由于這種方式成本較低,有大量成熟的開源庫可用,加上在AJAX中的X(ML)的“理論”指導(dǎo)下,許多開發(fā)者采用這種方式將對象輸出給前臺瀏覽 器,然后利用瀏覽器的XML能力進(jìn)行輸出顯示。從那篇文章中可以看出,這種工作是純粹的dirty work, 并且由于領(lǐng)域模型或者DTO的不同,輸出的xml結(jié)構(gòu)含義也不同,在對空值的處理上更是麻煩,在處理顯示邏輯的時候,基本上很難在客戶端對以這種方式傳遞 的XML以一種統(tǒng)一的方式進(jìn)行還原。以這種方式來進(jìn)行AJAX開發(fā),小規(guī)模應(yīng)用還不能顯出弊端,但是大規(guī)模應(yīng)用出現(xiàn),領(lǐng)域?qū)ο筝^多時,必然出現(xiàn)怨言。而我 們使用AJAX的真實意圖并非來無趣地去解析各種各樣的XML,而是需要XML中代表的數(shù)據(jù)。至于XML是什么樣子,除了調(diào)試階段,沒有人會關(guān)心。

          第二種XML的序列化方式是絕大多數(shù)跨進(jìn)程遠(yuǎn)程調(diào)用協(xié)議/框架所采取的方式。SOAP/WebService如此,XMLRPC如此,Buffalo采用 的Burlap也如此。這種遠(yuǎn)程調(diào)用的特征是,在協(xié)議約定的條件下,調(diào)用方和被調(diào)用方需要保證數(shù)據(jù)語義的完整性。拿什么保證?就是數(shù)據(jù)定義信息了。這些協(xié) 議的共同特征是采用謀一些標(biāo)記來描述數(shù)據(jù)類型:int, long, float, string, list...這樣定義完成后,只要根據(jù)協(xié)議,任何語言都能以一種通用的方式對數(shù)據(jù)進(jìn)行還原。AJAX引擎的概念也就漸漸呈現(xiàn)——通過某一種協(xié)議,他就處 于中間的位置,負(fù)責(zé)將調(diào)用方的請求包裝為協(xié)議,轉(zhuǎn)化為執(zhí)行方能夠理解的動作加以執(zhí)行;然后將執(zhí)行結(jié)果轉(zhuǎn)化為協(xié)議的值,傳遞給客戶端,客戶端引擎將協(xié)議內(nèi)容 解析為能夠理解的對象結(jié)構(gòu)傳遞給客戶端,然后就可以利用這個數(shù)據(jù)來顯示了。XML-RPC如此,WebService如此,DWR如此,JSON如此, Buffalo也如此。

          綜上所述,純粹使用領(lǐng)域模型特定的輸出XML傳遞給客戶端是一種相當(dāng)原始的做法。他只在很低的層次上印證了所謂AJAX的概念。然而,這種概念的深入思維結(jié)果便是一個AJAX引擎。

          文中提到的第二種輸出方式:HTML——應(yīng)該被看作WEB的一個特例,應(yīng)該說這是歷史因素、瀏覽器能力、設(shè)計者等多方因素達(dá)到的一個平衡。許多歷史應(yīng)用 中,大多采用將頁面進(jìn)行一定規(guī)則的分割,然后include或者jsp 2.0 tagfile的方式對公共區(qū)域進(jìn)行處理,留下一小部分進(jìn)行動態(tài)顯示。這里舉一個例子:查詢,顯示書籍列表。傳統(tǒng)做法就是上面一個搜索條件輸入文本框,下 面是搜索結(jié)果列表,處于同一個頁面。原來的搜索方式每次提交都要刷新整個頁面,用戶體驗不太好,現(xiàn)在需要改進(jìn)。按照激進(jìn)的Ajax做法應(yīng)該是當(dāng)搜索按鈕點 擊時,調(diào)用bookSearchService.search(String terms)的方法,取得結(jié)果列表,然后Ajax引擎處理結(jié)果數(shù)據(jù),將數(shù)據(jù)反序列化為javascript對象,開發(fā)者利用這些對象,要么利用DOM, 要么利用JavaScript Template, 在頁面對搜索結(jié)果進(jìn)行展示。然而,問題出現(xiàn)了:

          搜索結(jié)果太多了,用DOM操作速度太慢;
          開發(fā)者人手不夠,沒有時間,而這個頁面以前寫過;

          那么出現(xiàn)這種情況時,很可能的做法便是,見原來那個搜索結(jié)果頁面刨去其他不相干的部分,留下搜索結(jié)果部分,然后利用一個resultDiv.innerHTML=xmlhttp.responseText完事。這樣做,既達(dá)到了改善體驗的效果,也提高了開發(fā)速度。

          輸出HTML另外一種方式文中也沒有提及。事實上,HTML不僅僅作為片斷,更重要的是作為頁面視圖的一部分。在buffalo的demo中,可以看到所 有的頁面都被管理起來了,buffalo接管了視圖的切換;這種設(shè)計也存在于gmail/163新版郵箱中。這個應(yīng)用比上面的HTML片斷的使用方式還要 重要,因為這里是緩存可以介入的地方。通過不同的緩存策略,可以將用戶的實際和心理等待時間大大減少,從而進(jìn)一步改善用戶操作體驗,提升產(chǎn)品競爭力。 (PS. 在Buffalo 1.3中將加入客戶端緩存模塊,無需你動手,buffalo為你緩存視圖)

          文中提及的第三種方式,JSON,根據(jù)第一部分的描述,應(yīng)該比較清楚了。實際上他扮演了一個Ajax引擎的角色。這里不得不提的是,使用JSON的相當(dāng)危 險的。因為他的協(xié)議表現(xiàn)與語言本身綁定太死。如果某一天,JSON協(xié)議變化了,那么使用JSON的應(yīng)用基本上不可能應(yīng)對這個變化——因為返回結(jié)果是 eval()得到的。而Buffalo將協(xié)議隱藏起來了,1.2版本甚至連服務(wù)器端的ServiceInvoker都將burlap實現(xiàn)依賴隔離開。現(xiàn)在 使用burlap,也許某一天不用了,buffalo的應(yīng)用照樣可以運行。因為里面的細(xì)節(jié)都是透明的,作為開發(fā)者,你只需要關(guān)注數(shù)據(jù)對象本身,而非用來描 述對象的那一堆字符。

          評論

          # re: 正本清源:所謂Ajax輸出的三種形式  回復(fù)  更多評論   

          2005-12-30 10:02 by thinkbase.net
          兩種方式的XML示例代碼是不是搞顛倒了?

          # re: 正本清源:所謂Ajax輸出的三種形式  回復(fù)  更多評論   

          2005-12-30 23:19 by Vinson
          Buffolo did a great job to provide an Ajax Engine, it is something like DWR, even though the implemenation is different.

          In a real application, due to the maintainablity of the javascript, the less javascript, the better.
          So it is better to assemble/validate the object in the serverside,while javascript only need to collect the data just into a map. and this can be generic.

          Regarding the callback function, it can also be generic, the tasks that a callback function usualy like these.

          . update field values.
          . add/remove a dom node.
          . update the html fragment.
          . display errors/message.
          .change stylecss.
          . ...
          you call it a callback engine. I think buffalo need to add this feature.


          So there is no need to use JSON or xml, just keep the data in its original form, a Map of string, and then process them in the server side, it will make life
          easier.

          And the server side only need to return a collection of commands, the call back engine will know how to do it.


          Java is more controllable than javascript. If anything can be done either in javascript, or in Java, Just do it with JAVA.






          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 宜宾市| 舒兰市| 日照市| 温泉县| 府谷县| 阳西县| 西峡县| 尚义县| 伊宁市| 诸暨市| 个旧市| 长沙县| 新绛县| 石嘴山市| 江西省| 资兴市| 项城市| 长兴县| 桐庐县| 金平| 县级市| 温泉县| 津市市| 信丰县| 黔东| 黄冈市| 鄂托克前旗| 延吉市| 象州县| 无锡市| 大新县| 若羌县| 武乡县| 宾阳县| 靖宇县| 屏南县| 遂川县| 横峰县| 乐陵市| 义马市| 阳信县|