<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Sung in Blog

               一些技術文章 & 一些生活雜碎
    Java Web開發構想

    1.背景、形勢
    能夠進行Web開發的編程語言和技術很多
    (1) 動態解釋語言
    PHP; Perl; Python (Zope, Plone); Ruby (Ruby on Rails);
    (2) 編譯語言
    Java; .net

    Java Web開發遠非一枝獨秀:
    除了受到來自.net 這個重量級對手的最大挑戰之外,更受到Zope, Ruby on Rail 等新式輕騎兵的沖擊(當然,也繼續受到老式輕步兵PHP, Perl的沖擊)。

    官方Java走的是復雜路線,Servlet -> JSP -> Taglib。.net走的也是復雜路線,依靠成熟友好的集成化開發環境取勝。Java陣營好容易應對過來,從紛紜復雜的各種開發框架基礎上,發展出了重量級Web開發框架JSF,以及相應的集成化開發環境;渴望以此應對.net的攻勢。勝負未分,前途未卜。這時,另一個方向又殺來了新式輕騎Zope, Ruby on Rail。
    Python, Ruby等動態解釋語言,面向對象特性更好,先天支持 動態綁定、AOP、函數式編程、“編程即配置”等時髦概念。開發速度更快,代碼量更小,達到killer級別。

    傳統的HTML Web開發領域里面,Java已經是腹背受敵。領域外也展開了征戰,Rich Client Architecture的興起:AJAX(XMLHttp), Flash RIA, XUL, XAML, Smart Client(以及從前的ActiveX, Applet, Web Start)。

    Web的發展趨勢是 語義Web,最終目的是讓整個Web成為一個巨大的數據庫。
    這意味著,未來的Web應用將更加的面向文本內容數據,更加搜索引擎友好 – Search Engine Friendly.
    二進制的客戶端插件,如Flash RIA, ActiveX, Applet, Web Start等,雖然交互性能最好,但不是以文本內容數據為中心,搜索引擎不友好。所以,我只是保持適當關注。我更關注基于文本的UI表現,如HTML, XUL, XAML等。XUL, XAML還沒有廣泛流行,只是保持一種有興趣的關注。
    當下關注的重點,還是 XHTML + CSS + Javascript少量的 AJAX(XMLHttp)增加更好的交互性。

    我一直認為:輕量、簡潔、高效 才是硬道理。后面闡述我對Java Web開發的理解和構想。

    2. Web開發框架層次概述
    從上到下,Web開發框架的層次如下:
    (1) HTML, JavaScript, CSS等頁面資源。
    (2) 頁面模板層。
    如JSP, Freemarker, Velocity, XSL,fastm等。用來生成HTML, JavaScript, CSS等頁面資源。
    (3) Web框架。把HTTP Request調度分派到對應的Service Entry。
    (4) Business Logic.
    (5) O/R Mapping.
    (6) JDBC
    (7) DB

    根據我的經驗,一個典型的Web應用中的代碼比例如下:
    頁面邏輯約占 50%,商業邏輯約占30%, O/R 約占20%。

    但事實上,頁面卻是最不受重視的部分,從來都被認為是臟活,累活,雜活。典型的開發過程通常是這樣:
    頁面設計人員迅速的用Dreamweaver等生成一堆文本雜亂無章的頁面,然后交給JSP程序員加入更加雜亂無章的Java代碼和Taglib。
    當頁面布局風格需要改變的時候,頁面設計人員用Dreamweaver等生成一堆新的頁面。JSP程序員再重新加入更加雜亂無章的Java代碼Taglib。
    至于頁面中的腳本邏輯調試,更是一門精深的工夫了。

    根據社會規則,通常來說,工作內容越輕松,收入越高;工作內容越臟月累,收入越低;Web開發也是如此:做著最臟最累的活的頁面程序員,工資一般比不上后臺業務邏輯程序員。

    開發框架通常會帶來這樣的結果:讓簡單的東西,變得更簡單;讓復雜的東西,變得更復雜。
    這其中的原因在于:
    一般來說,一個應用中簡單重復的東西占80%,復雜特殊的東西占20%。
    簡單重復的東西很容易摸清規律,進行包裝,通用化。但是,在包裝的同時,經常就阻擋住了底層的一些靈活強大的控制能力。在復雜特殊的需求中,確實又需要這些底層控制能力,那么為了繞開框架的限制,付出的努力要比不用框架 大得多。
    打個比方,一個比較極端的例子。編譯語言比匯編語言的開發效率高很多,但是卻無法直接操作寄存器。當需要在編譯語言中操作寄存器的時候,就非常的痛苦。比如Java,也許需要JNI,寫C代碼,還要在C代碼里面嵌入匯編。編譯、連接都很麻煩。
    所以,一個框架的開發效率,就在于這個80%簡單 與 20%復雜之間的平衡。
    假如,不用框架來開發,簡單的80%要消耗 80個資源數,復雜的20%要消耗20個資源數,總資源數是100;使用了某個框架,簡單的80%只要消耗10個資源數,復雜的20%要消耗40個資源數,總資源數是50。那么,我們說,這個開發框架是有效率的。

    我的思路是,同時應對復雜和簡單。當然,為了應對復雜,簡單的東西可能就應對得不那么好。比如,做這樣一個開發框架,簡單的80%要消耗20個資源數,復雜的20%要消耗10個資源數,總資源數是30。
    這種開發框架是有可能實現的。而且是很有意義的。尤其是在復雜部分的比例提高的時候。越復雜的系統,這種開發框架就越有意義。

    后面的關于Web各層開發的論述,主要就按照這個“應對復雜、讓復雜更簡單”的思路展開。

    3.頁面資源
    也許有人會說,頁面資源,不就是HTML嗎?太簡單,太低極了,沒勁。Dreamweaver、Frontpage多簡單阿。隨便找個人來用就可以了。文本內容亂糟糟不要緊,瀏覽器里面顯示出來的效果好看就行。要增加炫的、酷的動畫效果,那就寫JavaScript唄。寫在HTML里面,看看在IE里面能不能運行就可以了唄。
    這也正是大多數公司開發頁面資源的方式。因為頁面的需求變化是最多、最快的,而頁面的制作成本很低,人們不愿意在上面投入更多的資源。

    我的看法是,萬丈高樓平地起。應用程序的每一個部分都應該完善管理,結構優美。越是需求變化多的地方,越是臟亂差的地方,越應該加大力度處理好。

    頁面結構方面,Javaeye論壇的Dlee做了很多工作。

    (1) 在 2005 年我們如何寫 JavaScript
    http://forum.javaeye.com/viewtopic.php?t=12973
    (2)使用 Unordered Lists 制作的下拉菜單和樹
    http://forum.javaeye.com/viewtopic.php?t=12995
    從上面的Dlee的論述和給出的資料。可以看出,頁面資源分為三部分:
    (1) XHTML。結構,Structure。
    XHTML里面的Tag部分只應該包括 <ul> <table> <p> <div><span>等結構布局Tag,或者<strong><emphasis>表示語義的Tag。
    XHTML里面不應該包括風格信息,比如字體、顏色、大小、粗細等,也不應該包括<font> <b> <i> <h> 等字體信息。
    XHTML里面不應該包括Javascript的定義和調用。

    (2) JavaScript。行為,behavior。
    JavaScritp應該存在于一個獨立于XHTML文件的獨立文件中。這樣可以做自動化單元測試。JavaScript應該只改變HTML DOM的結構和內容,而不應該改變它的風格。

    (3) CSS。Style,風格。或者說,Presentation,表現。
    前面說了,XHTML里面不應該包括JavaScript的調用。那么,XHTML的元素是如何JavaScript事件綁定起來?就是在CSS里面指定的。
    當然,眾所周知,CSS的本職工作是處理頁面風格。

    頁面資源方面,我完全認同Dlee的觀點。從技術和資源積累的長遠目標看來,這方面的初期投入的回報將是非常豐厚的。
    即使將來HTML消亡了,進入了XAML, XUL, RSS時代,這些結構清晰的各部分,重用的可能性都非常巨大。JavaScript + CSS + XML UI的這種經典設計思路,將留存很久。混雜成一團的HTML的命運只能是全盤被拋棄。

    4.頁面模板層
    頁面模板層是指Server端運行的用來生成HTML(或JavaScript,CSS)的Server Side Template Engine。
    這一層也是著名的臟亂差樓層。著名的HTML的Java代碼污染事件,就發生在這個樓層。不僅JSP有這個問題,其他的template, 如freemarker, velocity, tapestry等含有邏輯的腳本,都不同程度上有HTML的Script Logic污染問題。

    Dlee的做法很美。直接就不要頁面模板層,不用Server Side Template Engine。直接用JavaScript更改HTML DOM的結構、內容、數據。同時,會用到少量的瀏覽器端XSL。
    這樣帶來的結果,Template就是很干凈純粹的HTML,不含有任何Server Side Script。這個效果,和Servier Side Template 的 Jivan,XMLC達到的一樣。只是一個是在瀏覽器端執行,一個是在Server端執行。

    我研究比較了幾乎所有的Server Side Template Engine,力圖采眾家之長,避眾家之短,寫了一個Server Side Template Engine -- fastm, 能夠最優雅方便的實現頁面模板層。關于fastm,我的Blog上有不少文章論述。
    我的Blog,里面專門有個fastm 分類。
    http://blog.csdn.net/buaawhl
    http://buaawhl.blogdriver.com

    Fastm發布在java.net上。
    https://fastm.dev.java.net


    我仍然對Server Side Template Engine持肯定態度。基于如下原因:
    (1) JavaScript代碼量大、文件多的時候,不容易管理,不容易進行語法檢查,不容易跟蹤調試。
    這里有人會爭辯,Server Side Template Engine也用到了很多腳本阿,比如Freemarker, Velocity, 而且嵌在HTML中,怎么管理,怎么調試?即使是JSP,也是Java Code嵌在HTML里面,怎么管理,怎么調試?
    這里我要說,Jivan, XMLC, fastm,Wicket等Template Engine的邏輯都是在Java Code里面。

    (2) 用JavaScript生成文本內容,搜索引擎不友好。
    一般的網絡蜘蛛程序,只根據URL獲取HTML文本,搜索里面的文本內容,而不會執行里面的JavaScript腳本。

    (3) JavaScript代碼重用還是有些局限
    比如,有兩個HTML文件,一個是Table布局,一個是List布局。
    我有同樣的一批數據,要在這兩種布局中顯示。
    這時候,就要給這兩個HTML分別寫兩套JavaScript。這里面的DOM層次,元素,屬性都不同,再怎么定義ID,Class,也無法用完全相同的一套JavaScript處理。
    這里有人會爭辯,Server Side Template Engine也無法做到。別說JSP, Velocity, Freemarker等要在兩套HTML里面嵌入相同的代碼,就是Jivan, XMLC, Wicket也要分別寫不同的兩套Java Code,因為它們的XML DOM Node / Model View (Table, List) 都是不同的。
    這里我要說。fastm可以做到只用一套代碼邏輯。而且只有fastm可以。fastm的代碼重用率是最高的。

    關于Ajax(XMLHttp),我的意見是必要時才用,而且最好采用粗粒度的用法 -- JavaScript發出一個URL請求,返回一整段HTML,直接替換到頁面的某一塊,而不是用JavaScript來做這樣的把數據填充到HTML DOM中。如果你直接在瀏覽器里面輸入那個URL,也可以獲取那整段的HTML內容。
    典型的應用場合是Portal。Portal頁面的每個Portlet都含有這樣的 Ajax(XMLHttp) javascript代碼 -- 發出一個Portlet URL請求,返回一整段Portlet的內容,直接替換當前的Portlet塊。
    這樣做的好處是:
    (1) 減少JavaScript代碼的量和復雜度。
    (2) 搜索引擎友好。網絡蜘蛛程序可以辨別JavaScript中的URL,并根據這個URL,獲取整段處理好的HTML文本,進行內容搜索。
    有人可能會爭辯:如果URL請求返回的是XML數據,不是整段處理好的HTML,搜索引擎也可以進行內容搜索。
    這點我同意。前提是XML數據的內容是足夠連貫的,而不是散落的。比如,你返回的XML數據是“中國”。這個“中國”要放在HTML中的一個{country}位置,{country}足球。這個時候,結果HTML的內容含有“中國足球”。而XML數據中只含有“中國”。如果用戶用“中國足球”作為關鍵字來搜索,就找不到這個URL。

    從前面給出的fastm資料的連接中,可以得知。如同Jivan, XMLC, Wicket一樣,fastm的template里面不含有邏輯,所有的邏輯都寫在Java里面。
    有人會爭辯說:頁面邏輯寫在Java里面,我改變了頁面邏輯,還需要重新編譯。這也太不方便了。Velocity, Freemarker, JSP就不用重新編譯。
    這里我的看法是:業務邏輯代碼改變了,不也需要重新編譯嗎?頁面邏輯就不是邏輯了嗎?HTML里面的腳本怎么語法檢查、跟蹤調試?業務邏輯需要語法檢查、跟蹤調試,頁面邏輯就不需要語法檢查、跟蹤調試了嗎?
    對方可能會說:在我的應用中,頁面邏輯的改動需求非常頻繁,而且這些頁面邏輯非常簡單,不需要語法檢查、跟蹤調試。
    這里我的意見是:
    (1) 那就使用JSP, Velocity, Freemarker等腳本。
    (2) fastm, Jivan, XMLC, Wicket的Java代碼部分也可以寫在腳本里面,比如,Server Side JavaScript, Jython(Python), Groovy, Bean Shell 等腳本語言都可以很方便的和Java相互調用。

    fastm的生命周期將很長。
    HTML, XUL, XAML都是,或將是可以在瀏覽器或可視化編輯工具里面顯示的XML UI定義語言。Microsoft Office的Word, Excel, Powerpoint等格式都提供了相應的XML格式。這些XML文件都可以在Office里面顯示,并編輯。
    Adobe公司也提供了PDF的XML格式 -- XDP。可以在Adobe Designer里面顯示并編輯。
    由于fastm是Designer Friendly的XML UI所見即所得的模板技術。這方面具有很大的潛力。
    根本不需要第三方花大力氣專門做個IDE,來顯示自定義的Tag。目標文件格式提供商自己的閱讀編輯工具就可以直接用了,而且效果就是運行后產生的結果文件的效果。

    即使沒有可視化要求的場合。比如,Web Service需要的XML數據。fastm同樣有用武之地。比如,
    <!-- BEGIN DYNAMIC: users -->
    <user>
    <name>{name}</name>
    <address>{name}</address>
    </user>
    <!-- END DYNAMIC: users -->

    可以很容易的把一個Java Object List轉化為XML數據。

    另外,我不得不承認。瀏覽器端的JavaScript的頁面邏輯,可移植性要高于Server Side Template Engine。因為Server Side Template Engine通常是特定語言相關的。
    目前fastm是用Java實現的。由于實現很簡單,移植到其它的語言,也很簡單。如果是移植到Python, Ruby等動態解釋語言,那就更簡單了。我是有這個考慮,因為Zope, Ruby on Rails 的模板還是Logic 和 HTML混雜的,fastm這個思路有很大的用武之地。

    前面講了這么多。清理了兩層有名的臟亂差的老大難的樓層 -- 頁面資源層和頁面模板層。讓這兩層變得和下面的樓層同樣的優雅、清潔。

    下面該講到Web框架層了。在向下講之前,由于前面提到了腳本,我想先插入一段關于“可配置”、“可編程”、“可熱部署”、“腳本邏輯 vs XML Tag邏輯”的話題。把這個人們比較關心、討論比較多的話題,先講清楚。

    5.可配置、可編程、可熱部署、腳本邏輯 vs XML Tag邏輯
    由于Java是編譯語言,人們通常把變化的參數部分抽取出來,放到配置文件中。
    這些配置文件通常是XML文件。這很好,沒什么問題。XML很適合用來表達數據結構。
    但是,對于某一種技術的狂熱,通常引起對這種技術的過度使用,或者誤用。
    人們開始覺得,XML能夠表達一切東西,包括for, if, else等邏輯。這方面的典型例子有 Workflow XML Definition,Logic TagLib, XSL Logic Tag等。
    這點我不敢茍同。我的看法是,XML不適合表達邏輯,XML表達邏輯非常蹩腳。XML表達邏輯相當于自定義一門XML格式的腳本語言。

    比如,Logic Tablib,很難自然的支持 if else, switch。只能蹩腳地支持一堆 <logic:if> <logic:ifNot> <logic:exists> <logic:notExists> <logic:ifNull> <logic:notNull>。
    (注,好久沒有接觸過Taglib了。這些Tag Name都是憑以前的使用印象寫的,也許名字不對,但表達這些意思的TagLib都還是有的)
    如果要表達if () else if() else 就更蹩腳了。要進行非常麻煩的嵌套。

    再比如,XSL 支持if, else 也非常蹩腳。非要多出來一個層次才行。
    <xsl:choose>
    <xsl:when test="…">
    …. If ….
    </xsl:when>
    <xsl:otherwise>
    … else …
    </xsl:otherwise>
    </xsl:choose>

    同樣,如果要表達if () else if() else 就更蹩腳了。
    <xsl:choose>
    <xsl:when test="…">
    …. If ….
    </xsl:when>
    <xsl:otherwise>
    <xsl:choose>
    <xsl:when test="…">
    …. If ….
    </xsl:when>
    <xsl:otherwise>
    … else …
    </xsl:otherwise>
    </xsl:choose>
    </xsl:otherwise>
    </xsl:choose>

    可以看到,XML Tag 表達邏輯,非常麻煩,可讀性很差,完全是一種誤用,沒有半點優勢。當然,邏輯簡單的情況下,還是可以接受的。
    有人會說:XML表達邏輯,可以免編譯阿。
    那么我說:語法檢查呢,跟蹤調試呢?
    對方說:只是一些簡單的邏輯,不需要語法檢查、跟蹤調試。
    我說:如果只是為了免編譯,前面列出的那么多的解釋執行的腳本語言更適合。XML表達的邏輯,比Java等編譯語言還要麻煩很多,而腳本語言比Java等編譯語言簡潔多了,可讀性非常好,而且腳本語言和Java語言有很好的交互性,可以相互調用。重用、結構方面都具有優勢。

    有人會舉出Spring IoC為例子,說:你看,Spring IoC的配置文件不都是XML格式嗎?
    我說:
    (1) Spring IoC的配置文件基本都是屬性設置,Bean ID聲明。沒有邏輯。
    (2) 我也不是很贊同Spring IoC在XML配置文件里面引用Java類的做法。這方面,其它的容器如 Pico, Nano都支持多種配置方式,其中包括了不少腳本方式。我覺得,在腳本里面定義生成Java Object,比在XML中要好。當然,Web.xml里面也引用了Java Class名字。但那是非常簡單的情況。沒有嵌套引用、屬性賦值、構造參數等復雜的定義方式。XML適合描述一些通用的資源、數據、結構。比如,HTML, XUL, XAML,RSS就是XML用的恰當的例子。

    所以,我的基本觀點是這樣。
    (1) 純數據,不用說,應該定義在XML中。
    (2) 如果是系統中一些Java Object要用到的基本屬性。比如,連接池大小等。定義在properties, XML, Script中都可以。如果定義中沒有出現具體的Java Class名,傾向于定義在properties, XML文件中。如果出現了具體的Java Class名,傾向于定義在Script中。這個界限不那么明顯,兩者皆可。
    (3) 復雜結構的Java Bean的構造生成,那是肯定會出現具體的Java Class名,應該定義在Script中。

    關于“可配置 vs 可編程”,有一點要明確:只要是可編程的,一定是可配置的。但如果是可配置的,卻不一定是可編程的。
    這里的可編程,是指框架給程序員提供了API;可配置,是指框架給程序員提供了配置文件的格式寫法。
    “可編程”一定是“可配置”的。
    (1) 用戶至少可以自己定義配置文件,讀取參數,調用API。
    (2) 有那么多的解釋腳本可以直接和Java互操作,完全可以直接用來當作配置文件,定義參數。
    “可配置” 卻不一定“可編程”的。
    如果框架只給你提供了配置方式,而沒有API,那意味著,你只能進行參數的靜態配置。很難在動態期間改變這些參數了。你總不能嘗試著用代碼去改變配置文件的內容吧?即使你改動了,如果框架不進行文件的時間戳檢查,就是一開始裝載進來,就不再檢查更改了,你不就一點辦法都沒有了嗎?
    比如,Struts Tiles的XML定義,你只能靜態配置,你想在運行期間改變布局,沒有辦法。Site Mesh也是如此。而我們可以在運行期間任意操作XML DOM Node,別說布局了,任何東西都可以改變。
    所以,一個框架首要注重的是提供API,而不是提供配置方式。這是一個重要的原則。

    討論完了“可編程”、“可配置”問題,我們來看“熱部署”問題。
    XML配置文件、腳本文件支持“熱部署”當然要比編譯語言程序的熱部署容易得多。只要解釋執行前,檢查一下時間戳就可以了。要注意的問題,只是做好測試,因為沒有編譯期的語法檢查。
    不過,Java程序也是可以“熱部署”的。只是稍微麻煩一點。典型的例子是JSP, EJB Jar等。JSP修改之后,會自動編譯執行;EJB Jar丟到EJB Container里面,會被檢測到并裝載到JNDI命名空間。
    編譯語言Java程序的熱部署的一個可能的技術難點是,Class或者Jar已經存在,如何監測到Class或者Jar的更改,并裝載這個新版本,替換舊版本。
    這個問題我具體沒有研究過。從道理上講,應該在Class Loader上下功夫。如果需要,可以參閱開源EJB Container的相關實現部分。Java還有一種“Hot Swap”技術,專門解決這個問題,可以搜索查閱一下。

    這段小插曲,就到這里。下面討論Web框架。

    6.Web框架
    Web框架層是一個清潔的樓層。很多優秀的程序員在這一層大展身手,做出了很多好作品。我感覺不錯的有Spring MVC, Web Work。
    對于Web應用來說,Web框架層是最重要的一層。SOA、Semantic Web等效果都要在這一層實現。
    首先,我們來討論,框架的編程結構。
    我的Blog中有一篇《Java Web框架綜述》的文章。講解了一些流行的Web框架的編程結構,很多重復的內容不再贅述。
    http://blog.csdn.net/buaawhl

    Java Web框架綜述
    http://blog.csdn.net/buaawhl/archive/2004/12/21/224069.aspx

    Spring MVC的編程接口是最清晰的。大多數簡單情況下,Web Work的用法是最簡單有效的,編程結構比較特殊,可以說具有一定的變革意義。
    Spring MVC的Controller接口相當于Struts Action,也具有Request, Response兩個參數,雖然編程接口非常清晰優雅,但是本質上沒有什么變化。
    WebWork的Action則失去了Controller的身份,只相當于FormBean的身份,或者說相當于ActionBean的身份。WebWork Action不具有Request, Response兩個參數,它只具有屬性,并通過屬性Setter獲取HTTP Request的參數,通過屬性getter把結果數據輸出到HTTP Response。
    可以說,WebWork的這個把握是相當到位的。95%以上的情況下,程序員是不需要Request, Response參數的。當需要這些參數的時候,WebWork并沒有擋住路,可以通過實現RequestAware,ResponseAware等接口來獲取,或者通過一個Thread Local獲取。這種情況下,編程結構的約定,就不那么清晰了。

    我從Canonical的帖子和Blog受到了很多啟發。
    http://canonical.blogdriver.com

    jsplet:對Model 2模式的批判
    http://canonical.blogdriver.com/canonical/591479.html

    jsplet與webwork的概念對比
    http://canonical.blogdriver.com/canonical/594671.html

    從級列理論看MVC架構
    http://canonical.blogdriver.com/canonical/579747.html

    從Canonical的文章可以看出。JSPLet用JSP文件作為Dispatcher,然后在JSP里面注冊并調用對應的Object。這個尋訪Object的過程,完全是根據豐富的URL定義來做的。URL里面包括Object Scope, Object Name, Method Name, Method Parameters,天生就對事件機制有良好的支持。

    Zope的一些做法也有異曲同工之妙。
    Zope Object Publishing
    http://www.zope.org/Documentation/Books/ZDG/current/ObjectPublishing.stx
    http://www.plope.com/Books/2_7Edition/ZopeArchitecture.stx#2-3

    這種通過URL獲取Published Object的服務的思路,是一種實現SOA效果的有效思路。

    我們首先來看Web Service的現狀。目前Web Service主要分為兩大陣營。SOAP和REST。關于REST,請參閱
    http://www.xfront.com/REST-Web-Services.html
    關于SOAP和REST的比較、互操作,網上有很多文章。如果需要請搜索查閱。

    我個人比較傾向于REST風格的Web Service。
    因為SOAP是一門固定的協議,如果用SOAP來編寫Web Service程序,需要一個SOAP協議的解析庫 ,也許還需要一些專門的“SOAP 數據 -- 編程語言”映射庫,如同CORBA IDL的多語言映射一樣。如果你要讓自己的Web應用支持SOAP,你需要把發布的服務對象、方法都包裝為SOAP協議,這需要一些編程語言相關的數據結構的映射工作。
    REST則只是一種風格,而不是一個協議。中心思想是簡單的通過豐富的URI定義 (如XLink + XPointer等) 獲取資源。如果你要讓自己的Web應用支持REST,那么很簡單,只要在URI上下功夫就可以了,比如,多增加一個參數format=REST,在程序中多增加一種XML輸出格式就可以了。(從道理上來說,SOAP也可以這么實現,但SOAP的輸入和輸出都要遵守SOAP協議,SOAP的輸入參數一般都包裝在SOAP信封里面)

    關于HTTP Get和Post,我表述一下自己的看法。
    我認為,Web的精髓在于Get,而不是Post,在于獲取服務器的輸出,而不是輸入到服務器。即,Web的精髓在于以小搏大,四兩撥千斤。最經典的用法就是用一個URL,獲取一個長篇的文本內容,這個內容里面充滿了其他更多的資源連接。這也是超文本連接HTML發明的初衷。
    至于HTTP Post,則是這上面的一個擴展。B/S結構如此流行,很多應用都要轉移到Web上面,怎么辦,應用總是交互的,總要讓用戶輸入數據吧,就增加了HTTP Post協議。
    HTTP Get經典、簡單、有效。可以用豐富的URI定義把這個優勢發揮到極致。這個實現也比較簡單、優雅。就不多說了。主要的難點在于HTTP Post。下面的討論主要應對“HTTP Post”這個復雜現象。
    HTTP Post從來就不讓人們滿意。當輸入邏輯復雜到一定程度,表單數據的繁雜、凌亂、散落,到了服務器端很難組織起來。輸入方面B/S結構確實和C/S結構難以匹敵。于是,出現了XMLHttp,能夠把參數在瀏覽器里面組織成為一個統一的XML數據結構(或其他格式),發送到服務器端,一次解析出來。SOAP做這個方面,更是拿手好戲。所以,很多XMLHttp程序直接采用SOAP作為通信協議。而REST風格的HTTP Post則和HTML Form Post沒有太大的本質區別。
    REST在HTTP Get方面更勝一籌,SOAP在HTTP Post方面更勝一籌。可以根據Web應用的特點,根據HTTP Get / HTTP Post 頁面的比例,選擇適合的技術。
    我們再進一步分析HTTP Post的數據內容。HTTP Post的數據,可能包含三種類型:
    (1) 需要存檔在服務器的數據
    比如,用戶注冊時候,輸入的基本信息,用戶名、密碼、電子郵件等。這些信息要存放到服務器的數據庫。
    對于這種基本信息,HTTP Post,XMLHttp,SOAP處理起來,難度都不大,沒有很大區別。
    B2B的數據交換,也屬于這個類別。用何種技術區別不大。一般采用SOAP,因為SOAP是一種流行的標準協議。
    (2) 服務調用參數
    比如,用戶進行復合條件查詢的時候,輸入的查詢條件。這個時候,HTTP Post處理起來就非常蹩腳。而XMLHttp,SOAP則具有很大的優勢。可以把復雜的查詢條件很好組織成XML數據,發送到服務器端統一處理。SOAP里面甚至可以定義對象名、方法名等詳細的調用信息。
    (3) 指令
    這種情況比較少見。上面的參數類別中提到的“對象名、方法名等詳細的調用信息”,和這個指令類別有些交叉。
    假如一個SOAP調用方法里面的參數也是一個自定義的對象,這個自定義對象的屬性數據在SOAP信息中進行了定義。到了服務器端之后,服務端程序首先調用這個自定義參數的構造函數,生成這個參數對象,然后調用對應的服務對象,把這個參數傳給服務。這個過程可以看作是一個順序指令:[1]構造參數[2]調用服務。
    這只是最簡單的情況。而目前的Web Service一般也就支持到這個程度。
    我的看法是,一不做,而不休。既然都把調用信息定義到這個程度了,不如做的更徹底一些,全面完善的支持指令。這個指令則意味著邏輯。前面講過了,我不贊成用XML Tag表示邏輯,而贊成腳本。這里比較適合的腳本是JavaScript,因為JavaScript比較通用,客戶端、服務器端都可以解釋執行。注意,這里和一般的做法正好相反:一般的Web應用總是把JavaScript從服務器傳到瀏覽器里面執行,而這里是把JavaScript在瀏覽器里組織好,發給服務器端處理;這個JavaScript將會在服務器端執行,調用服務器端的對象。舉個SOAP含有JavaScript指令的例子 (只是示意,非標準格式) :
    <soap envelope>
    <XML Data>
    <a>
    <b>12</b>
    </a>
    <c>
    <d>21</d>
    </c>
    <e>
    <e>16</e>
    </e>
    </XML Data>

    <script>
    final_result = default;
    result1 = service1.service(a.b);
    if(result1.ok){
    result2 = service2.service(c.d);
    if(result2.ok)
    final_result = service3.service(e.f);
    }
    </script>
    < /soap envelope >

    這個好處是:
    [1] 發布了更多的基本Service。給客戶提供了更大的靈活度。
    比如,這里就發布了3個Service。由用戶自己組織邏輯。
    按照傳統的做法,上述流程將整個包裝在服務器端執行。發布給用戶的Service只有最外面的一個Service,而且高度耦合(if, else, if, else流程hard code在服務器端),不靈活,不通用。
    這里的方法,就可以讓客戶端隨意組織service1, service2, service3的調用順序和方式。
    [2] 減少了通信次數。
    假如這段Script在客戶端執行,那么和服務器要進行3次通信。

    傳統Web的權限控制一般在URL級別,這種script -> server方式的權限控制則要在對象級別、方法級別、Code片斷級別了,復雜很多,也許要大量應用Java的Code權限認證機制。

    以上展開討論了 Web Service, HTTP Get/Post。下面我們回到Web框架層。
    前面說了,JSPLet給了我很大的啟發。很多思路可以借鑒。
    當然,我并不贊成用JSP作Dispatcher, Controller。(1) 因為JSP要編譯成Servlet,而Servlet是Web Server管理的比較昂貴的資源。一個Web系統中JSP達到幾千個,就會遇到性能瓶頸。(2) JSP中的代碼重用很成問題。一般只能通過include file的方式。
    可以借鑒的思路。(1) JSPLet 的入口是JSP文件,這一步的URL到處理程序的映射是Servlet/JSP Container自然支持的。這是免配置的。(2) 豐富的URL參數定義,良好的對象方法尋址能力。

    我開發的開源Web框架lightweb,將具備如下特性:
    (1) 支持兩個層次的編程接口。
    interface Action { void service(request, response, servletContext); }
    這個Action比Struts Action, Spring MVC Controller高一個級別。相當于Dispatcher, 相當于JSPLet的JSP控制文件。這個用來做最外層的入口控制。
    同時,也支持簡單的JavaBean.method的直接調用。相當于WebWork Action,JSPLet Registered Object。這個用來做具體的事情。

    (2) 支持豐富的對象尋址URI,比如http://my.com/myProject/myModule/myEntry.action?object=calculator&method=add&p1=1&p2=3
    這表示要通過 myEntry.acion這個入口,調用caculator.add(1, 2)方法。
    如果用URL Rewriter可以美化為
    http://my.com/myProject/myModule/myEntry/calculator/add/1/3
    看起來就很象XLink + XPointer了。

    (3) 免配置。或者說極少的配置。
    框架根據一定的匹配準則,把myModule/myEntry.action映射到
    com.mycompany.mymodule.MyEntryAction 這個類的service方法。
    這個service方法負責根據object, method的名字,尋找到對應的bean,并根據參數進行屬性設置驗證,并執行對應的bean.method。然后,把這個bean作為Model和template結合,輸出結果。
    同樣,template的獲取也是根據一定的匹配準則,根據myModule/myEntry找到
    Mymodule/myentry.html 或者Mymodule/myentry/calculator.html。

    這樣的lightweb就能夠同時對應簡單和復雜。復雜控制的需求交給Action接口來做,簡單的一般具體任務交給普通Java Bean去做。
    Web框架層可以做的非常復雜,可以做的非常簡單。Lightweb的目標,就是分成多個簡單的部分;各部分合起來就能夠完成從非常簡單到非常復雜的需求。
    接下來,我們來看O/R。

    7.O/R
    Hibernate, EJB Entity Bean產品,JDO產品,iBatis是比較流行的幾種O/R Mapping Framework。
    我做的一些工作中,經常涉及到復雜的優化過的native SQL,并且涉及到大量的批量復雜邏輯處理,現有的O/R框架都不能滿足功能和性能要求。

    我做出這樣一個lightor框架,思路借鑒了Martin Fowler的《企業架構模式》里面講述的一些O/R的Row Mapper, Column Mapper等概念。

    最經典的用法是:
    ResultSet rs = ps.executeQuery( a long complex native sql);
    //will return a lot of records
    A a = new A();
    B b = new B();
    IMapper aMapper = MapperService.getMapper(A.class);
    IMapper bMapper = MapperService.getMapper(B.class);

    While(rs.next()){
    aMapper.populate(a, rs);
    bMapper.populate(b, rs);

    businessLogic(a, b);
    }

    可以看到,Lightor不需要一下子把所有紀錄都放到一個Object List里面。完全可以隨取隨用。整個過程中,a, b只有一份,極大的節省了空間、時間,也極大的提高了開發效率,減少了重復代碼。
    沒有任何一個其它O/R能夠支持這種用法。這里面,lightor的mapper的populate方法需要ResultSet參數。一般的O/R不屑于這么做的,別說ResultSet,連Connection都想包裝起來不給你看。

    Lightor的設計思路也是同時應對簡單和復雜。Lightor的Mapper實體部分是自動生成代碼。類似于JDO的靜態Enhance。不同的是,JDO靜態Enhance直接修改bean class。而Lightor則不動原有的bean,只是多生成了對應的Mapper Source/Class。這種方式是最利于跟蹤調試的。至于發布部署,和JDO的情況差不多,不如Hibernate的動態代碼增強。
    這里我很羨慕Python, Ruby等動態解釋語言的

    這一層我主要關注的是性能,緩存策略等等,而不是簡便。我覺得,一個應用系統的瓶頸主要存在于O/R, DB層。不應該單純為了追求OO結構的優雅,或者編程的方便,而犧牲了一些可能優化的地方。

    關于Lightor的緩存策略, 我的Blog上有幾篇文章。
    http://blog.csdn.net/buaawhl

    數據庫對象的緩存策略
    http://blog.csdn.net/buaawhl/archive/2004/12/21/224184.aspx

    分頁 & QueryKey & 定長預取
    http://blog.csdn.net/buaawhl/archive/2005/01/08/245005.aspx

    8.總結
    我理想中的Web開發架構是這樣的:
    開發速度快,運行速度快,結構清晰優雅。
    具體到每一層。
    Web框架層主要追求 開發速度快。
    O/R層主要追求 運行速度快。
    頁面資源層和頁面模板層主要追求 結構清晰優雅。

    posted on 2005-10-24 11:24 Sung 閱讀(2086) 評論(0)  編輯  收藏 所屬分類: Java技術
    主站蜘蛛池模板: 中文字幕免费在线看电影大全 | 亚洲电影一区二区| 一本久久免费视频| 亚洲AV无码乱码在线观看| 亚洲成熟丰满熟妇高潮XXXXX| 女人18一级毛片免费观看| 中文无码亚洲精品字幕| 最近的中文字幕大全免费版| 中文字幕乱码亚洲精品一区| 日韩成人免费aa在线看| 在线视频亚洲一区| 亚洲一级片免费看| 免费在线观影网站| 亚洲精品在线播放视频| 亚洲一区二区三区免费在线观看| 日韩亚洲人成在线| 免费在线观看毛片| 巨胸狂喷奶水视频www网站免费| 国产亚洲av片在线观看播放| 99久久国产免费中文无字幕| 亚洲人成电影在线观看网| 在线a人片天堂免费观看高清| 国产精品亚洲综合网站| 久久亚洲国产成人精品无码区| 久久精品国产免费| 亚洲三级在线视频| 国产国拍亚洲精品福利| 国产白丝无码免费视频| 久久亚洲最大成人网4438| 国产一区二区三区免费在线观看 | 久久午夜夜伦鲁鲁片无码免费| 亚洲欧洲精品久久| 国产麻豆剧传媒精品国产免费| 精品国产福利尤物免费| 亚洲熟妇色自偷自拍另类| 免费国产高清视频| 免费精品无码AV片在线观看| 性色av极品无码专区亚洲| 亚洲色中文字幕无码AV| 日韩精品无码区免费专区| 一个人看的www免费在线视频|