Saturday, June 18, 2005

微軟新版XML格式與GNU不相容 阻擊開源軟件(不見得能成功)

牛虻說:
也許不少人沒有看懂這則新聞,有可能這是影響未來五年IT行業最重要的新聞之一。一直到昨天,仍然有人就XML、HTML的長長短短跟牛虻爭個不休,牛虻 這裡再次強調:XML/HTML不是同一層次的東西,實際上,HTML就是由W3C提供了視覺解釋標準的一種XML;XML要發揮作用,比自定義標簽更重 要的是解釋這些標簽的程序和方法,這就構成了對XML的專利。如同每個人都可以用漢語取名,漢語不是任何人的專利,但名字原則上卻是人獨有的,牛虻可以定 義<牛虻>是一個大色狼,因為它的所有權是牛虻的,但別人這樣做,牛虻恐怕有希望拿到一筆精神賠付呢!
微軟的Office是微軟的最主要收入來源,超過了操作系統,超過了數據庫,超過了其他任何東西,盡管,桌面操作系統才是微軟壟斷優勢的基礎。微軟把自已 的下一版Office建立在XML內容定義後的解釋上,不但微軟對解釋程序具有專利權,而且,對微軟自已定義的標簽含 義也具有專利權,他們不得按這種標簽開發相應的xslt和解釋程序。這樣,就把下一代使用微軟的Office的用戶死死綁定在微軟的賺錢機器上——但不要 以為這是非法的,微軟完全合法,甚至……牛虻覺得它是合理的。
在牛虻的眼中,用戶是比較蠢的,特別是中國大陸上的用戶是世界上比較蠢的那種用戶——免費為微軟搞低價傾銷還以為佔了微軟的便宜,還為微軟叫好,拿著些個 把微軟的IE包裝一層皮卻消耗多幾倍資源的IT或者另一種什麼MXXXX瀏覽器(忘了名字,反正記得特垃圾),卻比說比firefox這樣好那樣好——說 真的,firefox也沒有什麼好的,但牛虻使用它已經半年了,沒有一次彈出窗口:“發生錯誤,窗口關閉,將重啟IE,是否發送錯誤信息?”,而IE呢? 呵呵,目前是平均一天一次。這是為什麼呢?不是微軟的技術差,而是因為微軟已經把網景送進了地獄了,它乾嘛要做得這麼好?可以想見,一旦微軟通過標簽專 利,同時又得到盜版的支援打擊了潛在的對手的競爭能力,那麼微軟賺得最豐厚的市場之一,就是中國市場,那一批蠢得豬一樣的卻以為天下最聰明是他們的盜版 友。
但其中有一個變數,是微軟可能沒有考慮進去的,作為桌面霸王,微軟似乎下意識不願意承認一個事實:辦公軟件已經基本上夠用了,網絡共享的文件編輯和文件存 儲會令更精致的桌面辦公軟件變得更過時:如同二戰的戰列艦是最好看的,也是最過時的。道理是一樣的。



微軟新版XML格式與GNU不相容 阻擊開源軟件

新浪科技訊 美國東部時間6月18日(北京時間6月19日)消息,微軟即將推出新版Office Open XML格式,其免版稅許可證與GNU通用公共許可證不能相容。通過這種方式,微軟就可以阻止開放源代碼軟件使用這種格式。

  美國一位高級專利官員正在就微軟的這一行動提出質疑,他認?微軟的這種許可證在合法性和可執行性方面都有待商議,並暗示免費和開源軟件開發商不用理會微軟的要求。

微 軟于2003年底首次發布了Office 2003 XML參考描述語言(Reference Schemas)。微軟Office部門官員本月早些時候表示,他們計劃使這種新的XML文件格式成?Office 12的默認值。明年,擁有免版稅許可證的用戶可以使用到Office 12。

  但是,免費軟件基金會總裁和GNU GPL的制作者理查德-斯多勒曼(Richard Stallman)已經明確表示,免費軟件團體通過微軟的活動不會獲得任何利益。他認?,微軟提出的這種新格式,意味著用戶對處于這種許可證下的程序不能 進行任何修改。他說:“修改軟件的自由和發行修改軟件的自由,是定義免費軟件的兩種最必要的條件。如果這兩種自由被限制住了,那?這種軟件也就不是真正的 免費軟件”。

  微軟XML設計部門高級經理吉恩-帕?(Jean Paoli)稱:“微軟已經承諾要開放XML文件格式,那?就一定會這樣做。而我們也正在采取相應的行動。但是,使用這種XML文件格式的人,也不能將其 用于自己的程序。也就是說,處于通用公共許可證下的Linux以及其它的開源軟件,不能使用微軟的這種文件格式。”(飛雪)

Monday, June 13, 2005

應該如何使用標簽技術?使用EL,logic和hanva標簽庫完成複雜的後台處理功能的JSP示例

JSTL標簽是SUN帶頭與apache社區合作的?品,可惜從一出現就已經是一個過時的技術。SUN的軟件架構師似乎缺乏從顧客角度考慮技術取向 的能力,與微軟相比差之千?。就標簽技術而言,它的目的是令菜鳥中的菜鳥變得可以寫JSP,還是令一般程序員寫JSP顯得更方便,更好管理?顯然,SUN 的那位笨蛋架構師沒有想明白這個道理(越是看得多它的文檔介始,越是覺得那個家夥是個大笨蛋),把SUN數千名天才工程師的才智白白浪費了。

所有人都已經知道,JSP出現的目的就是?了讓程序員更方便地寫簡單的servlet,複雜的多功能的servlet是不容易用JSP實現的。而 JSP希望讓菜鳥寫java動態頁面的目的並沒有達到,這條,還不如ASP/PHP。在JSP中散布底層業務邏輯既不便于對象組織,也不但于代碼管理,非 常低效。這是發展出javaBean和標簽技術的原因;而JSTL呢,它的基本客戶邏輯竟然是?了幫助使用者更方便地把底層代碼散布在JSP上!?包括數 據庫連接?!所以這東西是一個新的技術實現落後目標的?品,面對市場需求整整慢了一拍。

唯一有點價值的是它的循環邏輯,這條還是很有用的。只不過能夠實現的不止它一個,struts.logic標簽就是很好用的一種,而且不用指向 http:/sun.xxxx/core什?的,事實上JSTL能夠提供的struts:logic也能夠提供。實際上struts幾個標簽庫中也就 logi,有點價值,bean也可以,其他的html是純粹和FormBean?核心的MVC設想框架提供的。即使這樣,就實用性而言, strutslib仍比sun實用得多。

struts標簽庫不能很好地面向數據對象,這是它的不足,hanva標簽就是?了補充這個不足。結合struts的logic庫,使用hanva 標簽可以達到在jsp中聲明和接收變量,可以實現多種邏輯,可以直接從底層獲得持久性非持外性的數據對象,處理並輸出——一個程序大致也就只有這些東西做 的。特殊的東西再特殊處理,直接完全使用標簽調用下層服務daemon程序完成絕大部分功能,已經可以做到了。

下面的論壇示例刪除程序是這樣的一個功能,可以處理任何的實現了hanvaDAO接口規範的表數據的刪除,包括對其相關數據記錄的同步處理。它接收 一個對象類型(ent),及ID,判斷這個對象(行記錄)是否存在,然後判斷它的sourceid和id是否一致(是主貼還是跟貼),如果是主貼,就把它 的從貼一起刪除,否則就只刪除當前貼,然後返回原來調用的一頁,如果出錯,就轉向到errors.jsp頁,顯示出錯信息。


<%--如果記錄存在就繼承內嵌邏輯,把該記錄定?ident名--%>
<%--判斷sourcid與id是否一致--%>

<%--取所有主從貼,集合定名?theobjs--%>

<%--?代集合內容,單個取名?theobj--%>

<%--刪除該對象--%>





<%--單個從貼,清除該對象--%>


標簽結束,根據nexto轉向到調用者,這樣段小代碼實際上就扮演了一個MVC中的c角色。如果需要輸出斷點,可以調用hanva:log 把實時內容輸出到log日志中。一個比較複雜的功能就此完成了。全程實際上只是進行了一次或兩次數據庫的訪問,如果是多個從貼,需要獲得它的串,這是可能 的第二次。注意標簽,它輸入一個條件,也可以輸入fields選項,得到一個ArrayList串(沒有 同步要求就不用Vector),如果不是?了翻頁,它可以代替hanva:list,使用上也更方便,沒有需要先設定一個dao.list對象。

我認?這才是標簽技術的真正用法:幫助程序員在界面清晰明確地調用後台的處理程序,方便面向對象的業務邏輯的建立,方便隱藏非表達層的邏輯;而不是變成把頁面搞得更複雜,堆上更多難懂代碼的又一套新方法。

相對而言,tags文件標簽技術顯得更現實一點。如同jsp是方便菜鳥(仍是程序員)寫簡單的servlet一樣,tags標簽文件是方便看到 Class就發抖的菜鳥象寫jspjavalet一樣寫標簽;顯然,是最簡單的SimpleTagSupport的變種,只有它才有一個體內容。也同樣, 充分利用Class類結構的編碼技術在這?沒有辦法實現。

JSP開發社團看來熱衷于在局部別具一格地提供一些局部方便性措施,卻常常忽略了客戶更大的一個要求:在項目開發中盡可能采用單一的標准的範式完成 所有程序。多使用一種小技術模式在局部方便了,全局來說卻是多管理一種一種技術,或者說程序員要多學一種只在局部有效的技術。這個邏輯錯誤從J2EE開始 就伴隨著SUNJAVA的技術發展,看來是它的不治之症。在筆者看來,與其多搞小動作,不如在核心一鑽到底,而小範圍內的方便措施,還是有有能力的客戶去 實現?佳。拙劣地模仿微軟去拍落後(也是非主流的客戶)的馬屁,將是SUN公司技術上最終失敗的原因。

http://blog.csdn.net/zwwwxy/archive/2005/04/24/360540.aspx

http://zwwwxy.blogchina.com/1431465.html

posted Tuesday, 14 June 2005

減少jsp文件目錄的維護成本,需要一種什?樣的JSP發布框架?

即使對于一個大部分基本邏輯都包裝在標簽/類/servlet/EJB中的網站,以至于在jsp中看不到任何的javalet代碼,隨著規模的擴大 和項目時間的延長,目錄中總是堆滿了越來越多的垃圾文件。有些文件本身不是垃圾,而是被包容的子文件,但是jsp服務器可不管這個,如果不是jsp後綴, 它就會被jsp把源代碼下載到客戶端;或者,同樣是jsp一樣時就讓維護者頭大。如果不是采用良好的文件策略,那?隨著規模的擴大,一般的中大型站點堆出 幾千上萬的jsp文件,其中每一個模塊分上幾十個,是非常正常的;這時侯,管理這些文件就成?一件艱苦的工作;事實上,如果不是多人分管的話,一個發布管 理員真正能夠維護的文件如果超出一百個,效率就會急劇降低。何況,還有更重要的sql文件,class文件,xml設置文件……。?什?總是努力使用 bean/fragments/標簽/ORclass(如EJB),這就是原因之一。事實上,從事過大型項目的開發員對于後期目錄中那種不知那個有用那個 無用但卻要?不管要?只能一個個識別的經曆,總是一種難言的痛苦。經曆過這種痛苦也會對可重用組件在項目中實際上降低了後期維護費用的感受良深。
要實現高度的重用性,減少需要維護的文件的數量,就需要對系統架構甚至前台框架都進行抽象,重用的方式除了Class等方式外,還可以使用 shellscript幫助,特別是對那種必須分割出目錄管理而實際上結構非常相似的類型。通過這個辦法,即使是很大的項目,也可以把需要維護的jsp文件,不含java類庫壓縮到一百個以下,包括用于包含的小jsp片片fragments。
良好的命名規則可以進一步提高對文件的識別,也便于使用shellscript按文件類型進行管理。?了防止被jsp服務器下載到客戶端,如果是與 apache結合的話,可以在apache中建立禁止下載的文件類型。我一般是把這種文件命名?jsp_,?了達到這種命名的規範性,甚至不惜把已經寫好 的程序改一遍,幸好,在良好的組織框架下,文件總是只有幾十個,並且只需要改一兩行的幾個字母。盡管如此,每次都仍是讓我感到生畏,這種規範工作的確是最 不令人興奮的。
建立良好的命名規則和目錄結構,也是?了可以有效重用已有工作的前提,但什?時侯應該達到重用呢?畢竟即使是很相似的框架類型,在面向重用要求時,就意味 著很多的if-else。logic:equal/present之類,在Class中可以通過接口和繼承實現代碼的高效率,而在JSP中,如果重用變型 達到三個以上,大量的if-else之類就令混帳代碼冗余廣泛伸延,而在jsp文件內部令維護難道大大增加一個檔次;或者一個簡單的要求就需要 include十次八次,同樣是加大了維護成本。(要知道,接手者,甚至是自已吧,過了幾個月,對于開發中的印象早就消失幹淨了。)
這是一個難以協調的問題,可以調整的空間很小:如果不重用而一個文件任務專用,意味著每次需求變動時要重複維護多個非常相近的文件;超過三個的話,也就等 于說這個文件建立方式是低效的。而如果文件複用的話,依靠在jsp中的判斷實現,那?文件變得難以維護調試的界限也是三個左右。希望把這種代碼包含進 Bean是愚蠢的選擇,Bean不是做這些事情的,原則上,非表達層只應該包含業務邏輯,不應帶有任何專用的表達層代碼,象html。
問題的焦點在于,JSP作?表達層的實現方式,本身缺乏對象抽象的能力,只能依靠在jsp中的邏輯判斷適應條件變化;而理想的MVC,view視圖需要的 是一個定義視圖表達形式的對象,jsp根據這個對象的設置生成框架需要的html代碼,甚至生成jsp本身。因此,實際上對于這種大型的站點來說,在數據 庫以及數據映射和業務邏輯的中間層以上,表達層以下,需要的是一個jsp的發布系統。這個發布系統根據用戶自已定義和開發的框架抽象,生成jsp目錄/文 件等。它到底應該如何運行,我還沒有明確的解決方案,不過這個系統會有用的。
Cocoon是另一種發布系統,不過不符合這個要求,他事實上是一個與目錄無關的xml轉換器,可以根據用戶定義的xslt轉換器以及客戶請求的文件類 型,通過不同的轉換器向用戶提供同一內容的不同文件類型,xml,html,pdf或者其他。事實上,由于在互聯網上存在著文件類型統一化和歸一化的自然 趨勢,因此,?了少量用戶的特殊文件類型要求讓系統增加一半成本,減慢一半以上的速度,只能處理少一半的文件,加了這?一個轉換層是否值得我是深表懷疑。 象特定類型的數據必須提供xml,(如SOAP),直接用servlet寫的應答程序就可以看作是一個全功能的轉換器,又何必另外再搞一個轉換器和控制器 來處理這種要求呢?除非所有文件都必須同時提供 xml/html/pdf,否則象cocoon這種框架,我相信是毫無意義的。
http://blog.csdn.net/zwwwxy/archive/2005/04/26/364322.aspx

http://zwwwxy.blogchina.com/1340936.html
http://javaxml.blog-city.com/jspjsp.htm

MVC實現中控制器servlet向jsptag轉變後參數維護方式的考慮

MVC模式提供了標准的表達層和業務層邏輯分離的模塊建立的原則,不過在JSP中實現MVC要面臨無狀態的環境,而狀態維護是MVC模式實現的前 題。因此,維護MVC中的狀態成?實現MVC/JSP時的最大難題和成本構成因素之一,它的缺點在struts項目中顯露無遺。狀態維護的困難最終表現? 多步控制參數維護上的困難,OPflow提供了一個試圖面對流程對象進行維護的方式,但隨著JSP標簽的出現,令JSP MVC中的C有可能更適宜用標簽實現,又進一步令整個JSP/MVC實現方式面臨又一次的檢討,但也可能是一次進步。


OPflow本質上是?了在WEB應用中實現MVC控制流而設計的。對于WEB應用中是否應該使用MVC模式,在技術社區中仍然存在很大的 爭議;而針對在網上兌現MVC模式的一些典型框架,象.net以及java的struts,在實際應用中都顯得不盡如人意,常常是得不償失。MVC在 WEB應用中的 Module問題上基本上達到了分層按功能劃分組件功能,V視圖部分以脫離業務和底層邏輯的方式顯視,這兩點都已經沒有太大的爭議;焦點在于C,如何定義 C?如何在沒有嚴格狀態保留的情況下安全地使用C控制器?在MVC模式中如果控制器每個操作,象每個servlet.action.do,都只是針對一個 目的對象(象一個訂貨記錄)的一個操作,那?也就失去了MVC的實際意義.把實際處理功能放在再下一級模件中實現倒也是一個妥協的辦法,不過,結竟那不是 正道,因?,這?討論的是是不可以使用MVC提供軟件開發和運行的效率。所以在實際操作中都是使用一些傳遞的參數,象"act"告訴控制器類型,通過變更 不同的參數從而進行不同的控制,以達到最大效率的代碼功能重用;這不一定是最大程度的功能組合,到底重用到什?程度合適,我覺得需要的實際的工作中按項目 要求進行微調。

同樣的邏輯也存在于V視圖上。如果開發者希望自已的視圖部分成?一個顯示框架(微軟的word,甚至是?覽器就是一個顯示框架),而不是每一種顯示 對象的每一種細節都必須是一個程序的話,也必須是根據不同的指示參數提取不同的內容,以達到最大效率的和最低成本的模塊重用。這樣,無論是C還是V,如果 不想讓自已的開發變成隨機延伸的數不清的功能過分單一又過分相似的C和V,就將面對著另一個困難:處理一連串的act參數。而這些參數一般情況是放在 request.parameter中傳遞。在與一些版友的討論中發現一些朋友會混淆參數所存的命名空間,我認?,session一般用于會話跟蹤的參 數,而不應與界面關聯;而application應該是全系統的公共變量;同理,pageContext應該是僅止于當前頁面;如果不明確這個命名空間, 會把自已投入參數混亂的陷阱。

由于WEB應用不存在象VC++/VB/JavaSwing那樣的單一運行時狀態保持環境,所以當出現多步操作而必須共享部分變量空間時,大致只有 兩個辦法:一是在session中建立面向操作上下文(對象)的helper,二是在request過程中維持多步的狀態變量一致性。前者是較通用的辦 法,但缺點也是明顯的,就是每一種操作都要考慮一種helper,然後使用Vector,arrayList但集合類型地變量進行維護;顯然, struts中的 formBean和DynaFormBean,就是這樣一種helper。後者如果沒有一些工具幫助的話,在多步操作中要維持變量一致性簡直就是一場惡 夢。而Oplfow就是這樣一種工具。

hanva.Opflow的設想是使用一個外置的xml文件,把界面的操作形式看作是一種對象,定義?flow,每一步操作對應的URL看作是 flow的一個元素step,通過判斷所在的step,按約定方式組織各個環境的變量,包括變量的邏輯轉換,象垃圾回收站中deleted將取反之類。在 它的幫助下,可以把不同的頁面輕松組成一個個一步接一步自動維護的WEB功能模件。設想合理,實現後的運行也很理想,不過在運行一段時間後,仍發現有不足 之處。

其一,是xml的修改必須重?應用才能重新載入內存;其二,對于頁面人員來說,""這樣的路徑顯得不太直觀。第三;這不是OPFLOW直接的問題: 在面臨權限控制時,基于action的控制器不便實現與jsp同樣的界面控制邏輯。後面這一條可以作進一步的解釋。這是指在WEB上開放的連接,理論上是 說所有人都可以同步訪問的,無論它是V 還是C,只需要符合相應的條件,就可以實現操作。如果不能解決這個問題,那?WEB應用本身沒有可靠性可言,但如果解決方式過分複雜,象每一個程序進行一 次複雜的PMI驗證,然後最後兩句執行實際操作,這樣WEB的性能很差,而且整個項目開發的工作量會成級數的倍增。解決這個問題的關鍵在于共享單一變量空 間(會話helper是一種方式,不過缺點有如前述),並由一個共用的訪問驗證組件完成驗證。由于這樣的組件是複雜的,如果在一套系統上維持兩套達成同樣 功能但機制不一的PMI組件,那?程序開發和維護成本也會成倍數增加。

Jsp標簽提供了解決這個矛盾的一個途徑,並且,在此前的文章中已經提取,jsp標簽可以看作是一種在jsp中行的可運行時配置變量的 servlet,理論上可以由servlet實現的controler也可以由jsp標簽完成,並且,它較servlet可以訪問jsp上下文空間,從而 能夠實現與jsp訪問PMI控制同樣的邏輯。這是我決定把servletcontroller逐步轉向標簽controller的原因,盡管標簽仍沒有解 決jsp難以維護頂級模板的缺陷。不過,這就影響到MVC中關鍵的C的角度,並且,實際上是把V與C使用同樣的技術方式(標簽)作?統一媒介加以實現了, 從而也必然影響到 OPFLOW。這樣一來,我的構件JSPWEB應用的整個項目基礎模式就出現了變化,雖然很可能是進步,但模式的成熟總是需要一些波節,它的優點和缺點也 必須在使用過程中才能真正體驗出來。

原來以?JSP控制器標簽的使用會大大降低opflow的必要性,因?opflow的其中的一個目的是彌補servlet不能方便地調節運行參數而 開發的;而調用控制器標簽的jsp頁面本身也可以作?參數調節的空間,這樣opflow的必要性是不是就減低了?但實際使用時卻發現對于運行時過程參數的 維護,opflow還是很有必要的,除非在標簽中集成原來的維護參數的底層代碼,這是可能的,因?隨著標簽的使用,jsp數量的增加已經不意味著太大的維 護量,它們實際上只是一兩個標簽的載體。至于如何合在一起使用才最高效,還需要在應用中慢慢總結,歸納出一套可靠高效的程序模式才算對得起自已此前的工 作。

從當前的情況看,操作標簽是對servlet控制器的更替而不是對opflow的更替,標簽本身不能簡單地實現低成本的參數維護;不過,在單一步驟 時,這是無意中發現的,由于ActionTag是使用了與Struts.ActionServelt同樣的轉向代碼,我並且加進了從若?空就從 header中取 referer的部分作?轉向目標;這樣一來,無意中就令單步操作在操作完畢後反回了同條件參數的顯示頁面——顯然,把標簽直接寫在這些頁面上也可以達到 同樣的效果。不過需要在標簽生效前先用logic.prisent之類的判斷一下是不是要先進行標簽標定的業務操作。

http://blog.csdn.net/zwwwxy/archive/2005/04/13/345658.aspx

http://zwwwxy.blogchina.com/1185354.html
http://javaxml.blog-city.com/mvcservletjsptag.htm

apache/tomcat的JSP?URL重?的SEO优化/二?域名的要?

Apache是用了很長時間,但也只是用了很長時間,要說精通還談不上。所以這四五天存在著補課的味道在?面:既然公司不能提供好的系統管理員,也 只能是自已兼任了。經過對Apache和tomcat結合後的進行SEO優化的處理,四五天後,對這幾件工具的基本邏輯框架有了統一的認識。


對URL重寫的了解需要是針對這樣的需求:偏向于HTML的SEO搜索引擎優化,以及提供不定量的二級域名便于模塊管理和推廣。搜索引擎不 能識雖動態頁面在技術上是不可能的;我認?最大的可能在于對于靜態的hardlink,如果不存在搜索引擎會得到一個404標識;而對于動態頁面,反應就 不一定了。這樣就不便于搜索引擎對索引維護和分目。

對Apache mod_rewrite的深入了解後,發現在它的文檔和介紹文章中常常缺少幾個關鍵性的導引;而過快地涉及到具體的細節。要理解mod_rewrite的 工作,首先是要理解,mod_rewite是針對目錄進行工作的。換言之,每一個目錄的RewriteRule是各自獨立的,每個目錄的重寫既是最高層的 容器同時也是最低層的容器,因此,RewriteRule定義的地方是在各個目錄所在的位置,或者是所在目錄的.htaccess中。

其次,mod_rewrite是缺乏邏輯功能的平面型規則集合,因此每一個目錄設置中都是每一條規則地進行重複性轉換,[L]僅僅是表明一次匹配結 束,它還需要重新匹配,直接沒有任何條目與之匹配後才會輸出請求,這樣,如果規則稍多不但性能會直線下降,而且還很容易陷入混亂,所以 mod_rewrite要慎用,使用mod_rewrite來匹配二級域名要小心。對此,mod_rewrite設計者是期望使用正則表達式匹配,或允許 用戶調用perlShell作?複雜匹配邏輯上的應用。但這樣就令開發變得複雜起來了。

由于 mod_rewrite是基于目錄級的,所以它的優先級低于虛擬主機設置;而VirtualHost主機的優先級也低于 VirtualDocumentRoot的泛虛擬主機設置。由于VirtualHost的ServerName基于IP頭的匹配不能使用正則表達式,因 此,使用VirtualDocumentRoot設置多級域名存在著非常大的限制,應用稍微多元化就會面臨著難以克服的沖突。因此,單純使用虛擬主機或者 是URL 重寫都是不太有效率的,這時侯主要路徑應該是使用html導引,這樣既可以滿足SEO喜歡hardlink的要求,也不會影響到使用者的?覽;最重要的 是,可以把主要解決方案集中到一個應用程序的範籌,簡化了項目技術,也就降低了項目的成本。

使用mod_rewrite和二級域名的站點基本上使用php大概是基于這樣的原因:會話的一致性維護。當mod_rewrite應用到jsp站點 時存在著很大的複雜性。由于mod_rewrite是針對目錄進行的,它必然幹擾到目錄的運作;而jsp的上下文由于根據基礎目錄作?應用程序的判斷的; 這樣,在目錄清晰的情況下,jsp在不同的域名和虛擬主機下面都能正常識別到所維護的會話,但一旦目錄不齊全,象使用二級域名,無論這個目錄解釋是來源于 URL重寫還是虛擬主機設設置,?覽器都會把它看作是兩個會話請求,從而造成混亂。因此,在jsp站點使用二級域名,除了使用硬的html連接導引外,別 無它法。當然,使用Redirect方式可以解決問題的,表面上,但這樣的話就失去了SEO的意義;而URL重寫本來就是?了SEO而進行的;那?又何必 搞重寫呢?


截取RewriteCond條件中的字符串作?改寫變量:
RewriteCond %{HTTP_HOST} ^([A-Za-z0-9\-]+)\.bbs\.home\.javanet\.edu$ [NC]
RewriteRule ^$ http://home.javanet.edu/_apphome/bbs/%1.html [L]
注意其中的()和%X,前者是正則表達式截取的內容,後者是按順序取變量;

截取RewriteRuld中URL的字符串作?重寫變量:
RewriteRule ^([A-Za-z\-]+)\.html /apphome/$1.jsp [L]
同樣地,注意它的()和$,後者是與ReWriteCond不同的地方。

另外要注意的是[L],盡管是鏈中最後一條,但與防火牆的過濾轉發規則鏈不同,這個L是本次循環結束標志,而不是整個改寫流程結束標志。重寫的邏輯是:
while(有沒有任一條匹配) loop;

而防火牆規則鏈是if-else-else......;

特別是象本人一樣開發過防火牆的,對這種規則的區別要特別注意,否則很容易陷入死循環。

http://zwwwxy.blogchina.com/1149090.html

http://blog.csdn.net/zwwwxy/archive/2005/04/09/340996.aspx
http://javaxml.blog-city.com/apachetomcatjspurlseo.htm

選擇jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯誤

許多人認?JSP是JAVA向微軟ASP挑戰的成功?品,到今天,圍繞著JSP方案發展出了TAG/EL等技術,JSP作?JAVA的BS前台界面 方案看來已經是無法逆轉。但在我看來,JAVA選擇JSP這種表達形式,恰恰是它最失敗的地方,是對ASP的一種拙劣的模仿,它本來可以做得更好的,甚至 可能據此讓微軟徹底退出服務器領域,但最終,卻可能成?足以令JAVA最終失敗的重大戰略方向性錯誤。


JAVA到今天仍具有微軟所有語言所不具備的優點,就以C#而言,只不過是形似而神不似。java最根本的地方不在于它的OOP,不在于它 是C++的語法優化,這些都不重要,而在于它的虛擬機機制,使它成?最佳的跨平台的服務器語言;而C#無論多?語法相似,都無法改變這樣一個現實:它只是 微軟CLI中的語言中的一種,它再成功,也充其量是取代了在windows運行的JAVA;某種程度上,C#是一種注定沒有必要存在的語言,在CLI中, 只需要一種就夠了,象VB.net。
JAVA到軟件世界帶來的最大的影響是令軟件真正出現了分層開發,出現真正的三層結構。盡管有些家夥吹噓他們的軟件是N層結構(真不要 臉!),其實究其實則,都只不過是傳統的CS式的兩層結構的變種,不能把函數每加一個就稱?一層噢!JAVA出現體現了軟件的創造性思維,但JAVA犯的 錯誤最大的地方就在于他毫無創造性地模仿了ASP,並且,竟然把JSP作?中間件的主要訪問手段加以發展。這是一個重大的失誤,也許,如果有一天JAVA 死掉的話,就死在這個失誤上面。

ASP的是模仿最早的livewire式的jsp和cofusion,livewire也是本人最早在項目中接觸的jsp,與後來的java jsp毫無相同之處。這種netscape公司的"jsp"與asp有共同的特點,就是完全沒有面向對象的特性,是純粹的解析性腳本語言,後來的PHP也 是這樣的?品,PHP本質上可以看作是Cscript。這些語言的出現原意是要滿足那些不懂計算機語言,從HTML美工轉行的半吊子程序員的能力需要,美 其名?讓美工可以寫動態網頁程度。不過,這個開發假想成了互聯網出現以來最大的笑話之一,美工式的程序員始終不能寫真正的動態網頁,反而讓真正的程序員去 做了美工的活了,最典型的?品就是struts。

java與此完全不一樣,它是一種需要編譯的語言,具有完全的面向對象的能力;所以,它如果能夠發揮這種特點,打敗其他的幾種腳本是毫無困難的。結 果,SUN的天才的笨蛋們(我覺得這種稱呼最客觀,既是天才,也是笨蛋),選擇了用坦克車去和捷達爭奪出租車市場,做起了JSP。而我認?, servlet才應該是它最佳的發展方向。今天,我已經忘記了當初是什?原因令我放棄了jsp而使用servlet作?項目解決方案的;只記得後來完全放 棄jsp是由于兼顧兩種形式在傳遞變量和地址時非常複雜,還不如光用一種。今天當我以?我當初錯了,而標簽/EL等技術的出現會令JSP不同往昔而再次在 重大項目中選用JSP時,(其中一個原因也是那個笑話的延續,希望不懂JAVA的維護人員可以在交貨後自已維護系統前台),隨著項目的進入,我記起了當初 放棄JSP的原因:一個是當時的代碼管理非常困難,JSP系統基本上與其他PPP類程序一樣是不可維護的;另一個原因就是JSP無法基于模板進行維護。前 者由于tag等的出現而緩解了,(從前也可以使用include sevlet的辦法達到接近的效果),後者仍然一樣,關鍵就在于不能複蓋已有的代碼。而在servlet中,重載一個方法是很容易的。

許多人以?servlet難寫,在doget/dopost/init/等中需要塞進那?多的方法;其實,這是一種誤解,這種誤解是沒有認識到 servlet本質上是一種java class,可以輕易公有私有的方法,也可以繼承,可以重載等等。因此,在servlet中很容易就可以形成一個全系統追隨的模板,一改一起改。相反,以 ?寫servlet就是在doget中用out.println輸出的,是把寫JSP的理解帶進了servlet;JSP編譯成servlet後,也正是 這個樣子的。所以它不存在繼承的價值。

那?對于複雜的html界面如何達到與jsp同樣的簡潔嵌入呢?其實很簡單。我當時的解決方案是使用${xxx}標記預置默認的方式,然後把這些帶 有大量html代碼的標記的文件存在某個目錄;在sverlt初始化時通過文件字節流讀入,使用一個字符串分析的組件(今天還在用呢)把標記轉化?相應的 實際動態變量。這恰恰就是今天的號稱最先進的EL 表達式語言的解決方法。真的,我一點都不覺得有寫servlet比一般的網頁程序難在什?地方。某種程度上,我覺得自已做了一個jsp解釋引擎出來了。

那?這種土?的jsp和真正的jsp有什?區別呢?最大的區別就在于它是把jspp僅僅看成是?servlet服務的html代碼庫,而不是 serlvet?jsp服務。換言之,這?的jsp是類似于今天的tile/Jspfragment的東西。一個小小的差別,帶來的效果完全不一樣,因? 它可以完整的發揮出java面向對象和繼承的特點;甚至可以象PB那樣將整個項目前台作?一個類"繼承"出來,再擴展和重整需要修改的地方。而這種能力, 是那些"P"語言永遠不可能做到的。但是,SUN偏偏跟在微軟屁股後面去拙劣地模仿JSP。


不妨回顧一下在BS前台最常見到的架構是什?? 是一個大的網站上大部分版面具有類似的框架布局,每個分欄中只有其中某處不一樣。JSP可以很容易地共用其中一樣的部分;但對于其中不一樣的部分就無能? 力。由于JSP不能形成頂級模板,而每一個大分欄中部內容不一樣,所以唯一的辦法就是每一個大分欄拷貝出一個jsp文件來獲得一個頂級框架模板;顯然,這 意味著對每一個文件的相同框架部分進行維護;項目越大,這樣日後更改的工作量越大。這時侯真的有點懷念servlet的功能了,對這種需求,只需要寫好一 個 servlet,其他的servlet繼承它,然後重載它的中央內容方法,就搞惦了。當前要達到類似要求的唯一辦法,似乎只能是在頂級頁面中使用if- else/equal-notequal判斷?include不同的內容文件。舍此,還有什?好辦法嗎?

JAVA的BS前台的正確的思路應該是以一個可以訂制繼承方法的servlet?核心,然後可以分解一些象jsp這樣的文件,類似今天的jsp中技 術都可以用到這些JSP文件中。也就是說,核心應該是一個可以定制的servlet,而不是提供一個工具,把jsp編譯成不可變的servlet。頂級文 件應該是servlet,而不應該是JSP,這就是我所說的。


我一個人是不可能與整個JSP社區作對的,不可能一個人完成SUN幾千個開發工程師的工作,既然SUN的某個天才大笨蛋選擇了JSP作? JAVA在 BS的表達主流,到今天,如果我仍使用JAVA作?前台界面程序的話,最好就是隨大流標准,而在幾年前,JSP完全不是標准,情況是不一樣了。不過,從今 天實際的體驗來說,我仍然強烈地覺得,SUN犯了一個嚴重的方法性錯誤。更?遺憾的是,SUN沒有做到的事情,讓微軟在ASP.net中有所體現了,所幸 微軟的東西從來不打算跨平台移植的,所以SUN還有一點機會。
http://blog.csdn.net/zwwwxy/archive/2005/04/02/334958.aspx

http://zwwwxy.blogchina.com/1081807.html

http://blog.csdn.net/zwwwxy/archive/2005/03/30/333818.aspx

http://zwwwxy.blogchina.com/blog/article_81038.521777.html

http://zwwwxy.blogchina.com/443048.html

http://cnjavaxml.blogspot.com/2005/06/jspbs.html
http://javaxml.blog-city.com/jspservletbsjava_1.htm

對《jsp作?BS前台主流方案是方向錯誤 》的歸納性解釋

《選擇jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯誤 》已經被不少網友轉載,並有許多反饋意見。現主要就負面的反饋意見的基本面進行一次歸納性的回答。

《選擇jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯誤 》一文是經驗角度對jsp選擇方向的一種質疑;其不受"公論"(公論對中國人的思維影響很大)的逆向思維方式本身就會引起爭論,本是意料中的。現把部分爭論回答歸納起來,學習、實踐、爭論、歸納、再實踐,這是取得提高和突破的途徑。

首先,JSP是一種WEB界面處理方式(不是語言),所以是否適用MCV模式實際在存在著很大的爭議。所以MCV模式作?JSP/SERVLET的 選擇依據是不合適的。不過,JSP/SERVLET的表達層的應用方式,是沒有疑問的,盡可能將業務邏輯層分離出去,符合項目需求控制和成本控制的原則, 最終將提高項目質量並降低維護成本。無論是那一種方案,將應用業務邏輯包裝起來,成?與其他模塊/層盡可能低耦合的類,也是一種必然的選擇,也是面向對象 的方式的體現;面向對象方式主要體現?繼承/接口,如果否認它的積極意義,也就沒有討論的余地了。

OOP誰都會接受的,但這?關鍵焦點在于,對象是什??在不同的環境,對象有完全不同的含義,脫離這點,OOP其實成了一個過分泛濫的無用的名詞。 在VB中它通常表示界面中的一個視窗組件;而在C++中,通常是處理的一組功能;在JAVA中的業務邏輯中,對象一般是有獨立意義的一種客觀事物,而當 JAVA用于表達層時,無論是JSP/還是swing.awt,它都象VB一樣表達一種view圖結構。到底表達什?,什?可以抽象,什?應該抽象,很大 程度取決于開發者的經驗習慣。

JSP中適用那種類型,首先要回憶JSP針對的開發模式/假想是什?,也就是JSP這種技術?品出現時的分析用例是什?。文中其實已經提到了最根本 的論點和解釋(居然有網友沒有讀出來),JSP用例是抄ASP的,也就是"希望非程序人員可以直接生成動態內容"的JSP,這是SUN選擇向JSP進化的 最根本的理由。文中最大的論據也在于:事實表明非程序人員寫不了JSP;所以JSP側重點本身就錯了,它應該選擇方便程序員的方向!

再回想一下各人接手的項目是什?形式的。或者是從個人開始,按客戶要求(甚至自已就是客戶?)直接開發系統;開發一個版反饋給客戶再修改第二版?還 是接手一批原型,一般是HTML,然後從這?著手抽象可以抽象的東西,包裝可以包裝的東西?即使是第一種情況,開發者包打天下,最經常的方式是什?呢?應 該是萬般抄開始,從網上找相近的網頁,變成HTML後修改。可見,可以把WEB的開發看作是從HTML開始的。問題的差別就在于是如何從HTML開始的。

如果認?是從HTML直接開始,從中通過插入各種生成值,也就是SUN最早假設的方式;最終生成簡單的網頁,當功能不太OK 時再一頁頁延伸,那?JSP的確是合適的選擇。順便說一句,如果生成的是邏輯功能簡單而頁面表達複雜的HTML,(這是中國式網站的最典型情況),JSP 的優越性是非常明顯的。不過反過來,這樣的缺點也就在于隨著項目的開展、龐大、複雜化,開發者和維護者最終都會陷入"網頁陷阱",也就是頁面變程序缺乏邏輯的聯系,變得難以維護了,這其實也是?什?要用動態網頁代替HTML的原因。

更通常的做法是在HTML上再處理,抽取出各個特征代碼,一一包裝起來成?可重用的組件,(注意和業務邏輯組件的區別),另一方面,組件中的 HTML代碼?了修改方便,要求修改後是無需編譯的。從這個要求出發,派生出了XML/XSL/XSLT一整個體系,也派生出了TILES,SLIDE, struts包括它的validator,等等。無論是那一種,HTML必須整理再分解才有可能達到重用和降低維護成本的目的。對于功能/內容/服務驅動 的網站,網頁一般簡潔並功能模塊重用性高,這種操作方式尤其顯得高效而簡潔,網頁本身就可以直接用UML/USECASE的方式預先設計。這就是《選擇 jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯誤 》中假設的項目類型,也就是這時侯,對象的繼承對于表達層才有現實的意義。

事實上,JSP也是基本支持上面的網頁分解、抽象、重用,最經常是使用include方式;在taglib和struts:logic中,還可以根 據上下文變量條件決定include,所以也基本上達到了類似的目的。《選擇jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯 誤》一文爭論的是,是JSP不能處理重用頂級模板,限制了這種表達層對象抽象重用的水平。如果選用servlet?主要方向,同樣的投入,要達到方便程序 員直接修改界面代碼,同時也便于(選擇)各個方向層次的對象應用,就沒有JSP那樣的障礙的。SUN在開始JSP時是一個無負擔的開發者,完全可以這樣 做,但卻選擇了與ASP雷同的用例方案,沒有利用自已最大威力的對象語言,把JAVA降格成腳本(javalet),最終不得不通過開發標簽 /javabean來彌補原來的不足,不但加大了學習者的負擔(就以Tag而論,能熟練使用的jsp程序員有幾何?),也減少了自已的市場份額和市場成功 的機會。這就是對《選擇jsp而不是servlet作?BS前台主流方案是JAVA的戰略性方向錯誤 》批評SUN是笨蛋的原因。

無論如何,IT/軟件行業,是一個支持獨立思考,支持創造性思維的行業,可以懷疑一切權威,在實踐中體驗並用實踐來證明,是軟件行業技術進步的基 礎,也是IT行業存在的基礎。這不是一個子日詩雲,權威(老師)定論的領域,如果否認這一點,象一些人表現的那樣對權威的奴性崇拜,也就沒有什?再討論的 必要性了。

http://blog.csdn.net/zwwwxy/archive/2005/04/02/334958.aspx

http://zwwwxy.blogchina.com/1081807.html

http://blog.csdn.net/zwwwxy/archive/2005/03/30/333818.aspx

http://zwwwxy.blogchina.com/blog/article_81038.521777.html

http://zwwwxy.blogchina.com/443048.html

使用ConnectionManager適應多數據庫的應用環境

今天企業應用環境中一般情況下要面對不止一個或一類數據庫;另一方面不同時期的不同種類的數據庫形成一個個的荒島;在java中,技術潮流傾向于不 是直接操作數據庫記錄,而是通過中間層的數據庫對象持久化處理達到OO的目的。無論那一種,都要求比較容易地面對多個數據庫連接。多個數據庫連接比較?人 所熟悉的是微軟的ODBC數據源設置,除了沒有實現中間層持久化外,ODBC其實比JDBC要全面也更容易處理。ConnectionManager是一 個通過 XML設置的,類似于ODBC數據源設置的東西,通過定義dao.Connection對象,程序可以按需要以:
java.sql.Connection conn =ConnectionManager.getConnection(${connectionname});
得到所需要的連接,從而簡化了在多個數據庫環境下的編輯工作。


現在項目開發者面臨的常常是多個數據庫的應用,曆史的和不同部門的,有CS後台的也有BS前台的。各個數據庫的數據必須融彙到同一個業務邏輯中,否則就成 ?一個個低價值的數據孤島。應對這種需求,目前使用了兩種技術,一是數據對象化技術,實質就是在數據層和應用邏輯層中間插入一個持久對象化層,通過程序或 容器使數據對象與數據記錄相一致,而應用邏輯直接訪問數據對象而不是數據庫記錄;二是通過使用全局目錄調動使用多個數據庫供數據對象化管理層使用。無論是 EJB ENTITy,還是Hibernate,抑或是我處已寫的Hanva Processor都是這種思路的一種體現。

並不總是需要采用EJB才能管理多個數據源,何況大部分項目中采用EJB帶的是更高的成本和性能的更低效,開發工作更複雜化,甚至只是碰運氣地填代碼再發 布不行再填代碼再碰運氣,(我本人很討厭這種開發感覺,所以搞了一個Hanva的小項目,除非客戶指定EJB了)。不過EJB容器中管理多個數據源的方式 還是很值得學習的。大部分情況下,它是通過初始化後的數據源對象,象連接池,注冊進JNDI SPI;然後通過java.naming.Context.lookup()這個全局名稱(在JVM範圍內)。我的做法是由寫一個 ConnectionManager,它由一個xml文件定義多個數據庫連接相關的參數,在ConnectionManager初始化時讀入內存。使用時 然後通過調用ConnectionManager的靜態方法getConnection (String connectionname),就可以得到指定數據庫連接。由于實際上操作數據庫連接的都是Processor和Lister兩個類,這樣,要保證連接 資源的釋放也是很有把握的。依靠這個方法,就可以在輕型的應用中都可以搞妥多數據庫,使用數據對象化方式進行開發了。

connections.xml定義:


connection-set供ConnectionManager使用,可以按需要取用不定的多個連接定義,代碼完全不變。從而適應多數據庫的使用環境;
]]>






uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="dcon" password="girlfriend" />
uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="erso" password="abc" />
uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="eef" password="qwewer" />
uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="system" password="manager" />

ConnectionManager方法:

public class ConnectionManager{
private static LOGGER logger =(LOGGER)Loger.getLogger(Constants.LOGGER_DAIFU_KEY);

public static synchronized java.sql.Connection getConnection() throws java.sql.SQLException{
String name =Repository.getInstance().getConn();
return getConnection(name);
}

public static synchronized java.sql.Connection getConnection(String name) throws java.sql.SQLException{
if(Repository.getInstance()==null){
logger.error("the repository for dao operation has not been initialized");
return null;
}
dao.Connection conn =Repository.getInstance().getConnection(name);
String dri =conn.getDriver();
java.sql.Connection cn =null;
try{
if(dri.equalsIgnoreCase("datasource")){
javax.naming.Context initCtx = new javax.naming.InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource)initCtx.lookup(conn.getUri());
cn = ds.getConnection();
}
else{
Class.forName(dri);//no newInstance();only get class
cn = java.sql.DriverManager.getConnection(conn.getUri(),conn.getUsername(),conn.getPassword());
}
}catch(Exception ex){
String msg ="ConnectionManager.class,conname:="+name+";dri:="+dri+";cn:="+cn+";msg:="+ex.getMessage();
logger.error(msg,ConnectionManager.class);
throw new java.sql.SQLException(msg);
}
return cn;
}

public static synchronized java.sql.Connection getConnection(dao.Connection conn) throws java.sql.SQLException{
if(conn==null){
System.out.println("the dao.Connection to getConnection is null;");
return null;
}
String dri =conn.getDriver();
java.sql.Connection cn =null;
try{
if(dri.equalsIgnoreCase("datasource")){
javax.naming.Context initCtx = new javax.naming.InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource)initCtx.lookup(conn.getUri());
cn = ds.getConnection();
}
else{
Class.forName(dri);//no newInstance();only get class
cn = java.sql.DriverManager.getConnection(conn.getUri(),conn.getUsername(),conn.getPassword());
}
}catch(Exception ex){
String msg ="dri:="+dri+";cn:="+cn+";msg:="+ex.getMessage();
logger.error(msg,ConnectionManager.class);
throw new java.sql.SQLException(msg);
}
return cn;
}

public static void main(String[] args) throws Exception{
if(args==null || args.length<2){
System.out.println(" Please input the xml and conn's name");
return;
}
Repository.parse(args[0]);

java.sql.Connection conn =getConnection(args[1]);
System.out.println(conn);
}

}

調用時只需要

java.sql.Connection conn =ConnectionManager.getConnection("connn");

就可以得到指定方式的數據庫連接。

http://blog.csdn.net/zwwwxy/archive/2005/04/01/334718.aspx

http://zwwwxy.blogchina.com/808527.html
http://javaxml.blog-city.com/connectionmanager.htm

優化apache/tomcat配置

有充分證據表明現得絕大多數的apache/tomcat配置中,apache根本就是擺設,所有的響應負擔,包括靜態多媒體文件實際上是由tomcat 完成,而tomcat實際上是效率相當低的,大約是apache的十分之一。因此,沒有達到集成兩者的目的;但在優化配置本地基本成功,打算在網上測試服務器實際試行時,卻碰到了"martix現象":無可解釋的不可重複的異常表現。


看來,在tomcat/apache的配合上要動真格的,今天寫的那份文章提示了一個現實的問題,apache根本就沒有作用,更嚴重的 是,107 和106上不匹配,107上甚至不能重複出106的配合。由于圖片的量會不少,所以這是一個非常現實的問題。我想,目前唯一的辦法就是下載到本地,參考可 能參考的資料完整地進行一次配置。畢竟,現在的配置是幾年前的,而且不是由我進行的。這?如果處理OK了,那?相信對于提供系統的處理能力和處理的速度, 是大有益處的。......經過一天的奮鬥,主要的時間在于重新在本地設備上安裝所有相關的軟件,包括本地的DNS服務器,沒有這個沒有辦法測試虛擬主機 解釋。所以主要還是在晚上測試,深入鑽研apache/tomcat的配合,基本搞清楚了兩者的關系,確認原來的配置方式只是"表面上成功",實際上完全 由 tomcat完成所有應答,apache只是聾子的耳朵——擺設。但是在本地完成所有測試,原封不動地准備在網上進行更新設置時,再次碰到"Matrix 現象":出現了莫名其妙的差異;無法解釋,自然消失。

第一個差異就是,按照最新的理解,apache解釋的多媒體路徑與tomcat解釋的頁面路徑是不同的,因此,必須在頁面上修整兩者,否則圖片和多 媒體就會因?路徑不一而不能獲取;而在原來設置中由于完全由tomcat解釋,所以兩者是相同的。這個設想的實驗在本地非常成功,但是在網上,就完全相 反,路徑解釋無論如何都是對的——問題在于我在本地已經測試並修改了這個路徑解釋:老天爺,到底要那一個呢?而實際上, worker.properties的過濾是完全一樣的。這點如果還不算太怪的話,那?第二個差異就更怪了。

首先是使用原來的httpd.conf總是在虛擬主機DocumentRoot上被禁止訪問,在強行使用本地設置文件置換(由于路徑一樣,問題倒不 算大)後就變得可以了。這條權作是未知的某處錯誤存在,那?隨後就怪事連連了:無論是那個虛擬主機,統統只是解釋到第一個虛擬主機的目錄,換言之,虛擬主 機完,全失效。把那個設置文件拿回本地測試卻是一切正常。隨後再次到網上測試,這次卻是跟著正常了......原因不明,唯一的可能......似乎是 firefox緩存一類......總之是筆糊塗帳。真是莫名其妙。但前者的圖片必須改由apache解釋是確證無疑的,否則,系統性能會過大消耗,靜態 大文件的處理,不是tomcat的長處。


我們這個世界是一個物質物理世界,它的基本特征就是同質可重複性,整個現代科學都是建築在這個基礎上的。如果一旦碰到同質可重複性不能成立時,我的感覺就是俺是不是生活在Matrix?頭了。


續:
今天在本地的測試得到了與遠端同樣的結果,至少看來重新象一個物質世界了! 目前唯一可能的解釋,(不過也是解釋得非常牽強的),就是firefox對于?覽過的網站或者出于加速的原因,有一些與過往的?覽器有很大不同的緩存策略。在以後的操作中要注意這一點。


這個結構許多人已經熟悉用了,而且在網上也有大量的howto,不過最關鍵的文件 worker.properties設置就未必正確,如:

info=Ajp13 forwarding over socket
tomcatId=localhost:8009
[uri:/jsp-examples/*]
[shm:]
disabled=1

如果象上面那樣uri:/jsp-examples/*的話,相信,apache屁用沒有,根本上就是tomcat承受了一切的負擔。 顯然,如果是這樣配置,系統承受的負擔,我指的是java 服務器,將是大大超出應有的負荷的。應該修改上面的配置,讓apache承但,主要是html和圖片以及多媒體的下載任務,而不是tomcat,估計可以大大提供這個搭配系統的負載能力。


......
前天寫到這?,忽然覺得這個配置頗?眼熟,趕快去查一下,果然現在的項目中的設置就是這個樣子的,但是進一步的測試就 讓我有點入歧途,一會兒證明是那樣,一會兒就表明是那樣。軟件這東西如果缺乏邏輯必然的聯系,人是沒有什?好幹的。無論如何,繼續上面的思路,象上面的配 置,表明所有/jsp- examples/*次級目錄下的東東都是交由tomcat處理;Apache並沒有相應的工作。正確的配置應該是:
[uri:/jsp-examples/*.jsp]
[uri:/jsp-examples/servlet/*]

如果使用了如struts,大概還需要增加*.action這樣的後綴。這樣,非此類型的文件將會交給apache。而這樣的設置:
[uri:/*]
有極大的危險,將意味著所有的請求全部由tomcat響應;不過,看來ajp13作了預防性措施,事實上,這時侯ajp13把所有請求扔進了下水 道,什?也不幹。負作用就是虛擬主機的根目錄我無論如何設不出它能夠直接識別index.jsp引導。只能使用html代替,不過,這也沒有什?大不了 的,如果是小型的首頁,可以就地轉向,而假如是大型的首頁,本身就會定時轉換輸出?html頁面。顯然,在這種結構中使用通配符是最容易配出運行框架的, 卻也是錯誤的。


把Apache與tomcat合並起來後,還得到了一個意外的收獲,就是可以使用連接形式把一些主要的非jsp/servlet文件由apache在目錄 以外解釋,從而簡化了開發目錄的管理。在實際的開發過程中,如果規劃不佳,不多久就會積累了大量的無用的圖片文件,工作目錄動不動超過一個G是非常正常 的;如果開放部分如允許用戶上載文件之類,更是大得驚人,但是由于tomcat不能解釋symbolic鏈接,這樣就不能把這些圖片移到目錄以外,只能是 使用全url才有可能實現,而把在合理配置 Apache/tomcat後,盡管tomcat不能解釋鏈接符號,但Apache能夠,這樣,就把上面的問題解決了。

http://blog.csdn.net/zwwwxy/archive/2005/04/11/343533.aspx

http://zwwwxy.blogchina.com/676895.html
http://javaxml.blog-city.com/apachetomcat.htm


使用jsp完成文件可定制上載

這幾天的工作主要圍繞著文件(主要是圖片)上載,並可以在線和HTML編輯器集成,操作簡便與目前引用網上圖片相似。我是有點小看了這件事情,不過也不無 道理:一來以前使用servlet完成過,其中的核心DoUpLoadBean也的確是可以工作;其次集成到編輯器則在使用php的本人的私人博客上做 過,看不出有什?特別難的地方。但實際上在展開後就發現,簡單實現上載是容易的,但要合理地安排上載的策略,就不得不小心翼翼。因?允許上載本身是非常需 要危險的,這實際上是開了一個口子;允許客戶對服務器進行事實上的操作,上載攻擊從來就不是一件困難,更不是一件罕見的事情;可以想見一旦系統開通,這類 攻擊必然就會發生。


另一方面,在允許用戶上載本地文件同時就必須考慮後期的管理,因?,即使是在用戶本地,最大的硬盤也會過不多久就會給說不清是什?東西的垃圾占滿;何況現 在是允許許多人同時使用的服務器,如果沒有精確的策略,花不了多長時間,客戶的上載文件就會把系統撐爆。就在上一個星期,一位朋友向我求助,說是他們的數 據庫達到30G,把硬盤吃光了,結果死了機;對此,本人只能是愛莫能助,因?,可以肯定?面絕大部分是垃圾,卻搞不清什?是垃圾,什?是必須的。因?,他 們缺乏一個策略。而且,就算用戶不是惡意的,大部分情況下,在開通開載的時侯,很快硬盤也會撐滿,如果這是系統盤,通常就意味著崩潰,可見,必須使用連接 把上載限制到另一個專用的分區,以確保安全。通常鐵quota在這?是派不上用場的,因?那需要把WEB帳號與操作系統帳號結合,既複雜又危險,更加沒有 這個必要。同時,上載的文件如果不是給每個用戶分配目錄,也應該是在每個用戶的名稱前增加一個前綴,以供識別;這樣,萬一需要清理,配合文件日期,可以使 用find/grep/rm組合腳本進行備份或清除,至少是有可能的。
還有其他因素,導致上載文件實際操作比簡單接愛一個文件上載的程序量要大得多;其中主要包括權限控制,(考慮到可以用上載進行攻擊,這條不得不小心點), 文件管理,以及修改屬性,包括大小,類型限制,可以方便修改存儲的方式等等,事實上,就完成情況下,上載部分只花了五行程序,而管理則不小于50行。
今天已經不必再自已寫輸入流了,就算自已沒有積累,還是可以從網上找到開源的代碼,象jakarta commons upload就是一個。這個東西沒有什?例子,所找到的例子大部分是跑不動的,倒不是怪程序員自已,而是這個東西不但沒有什?文檔,還把方法和類也改了: 例子說的UpLoad實際上是DiskUpload,而當前的Upload有什?區別,?什?可以省去設置內存耗量的等部分,我找不到任何的解釋。雖然對 自已的代碼有所偏愛,但由于我的代碼不能處理多個file上載,雖然,這種情況實際上也很少,我卻一直弄不明白有什?辦法可以識別不止一個上載請求,這意 味著我對RFC1864仍是欠了解的,既然有更可靠的東東,就不要太偏心自已的東西了,結果把用了幾年的DoUploadBean徹底地埋葬了。
在選擇是使用jsp還是servlet處理上載時,顯然兩者中servlet更規範一點,但在權限控制上頗?不便,因?,所以識別變量必須通過 request獲取,這也意味著存在客戶端?造變量直接提交上載的可能性,確保正確識別意味著大量的代碼。我最終決定采用自已發明的使用jsp標簽取代 servlet的辦法,(參看《可以使用多個jsp標簽達到類似servlet效果》一文)。結果表明,這的確是兼有 jsp/servlet/javabean優點的好辦法,特別是修改非常容易,我改個主意要以用戶名稱開目錄,只是改了標簽一個定義屬性就搞妥了,這才真是易用性的體現。

最終的使用方法很簡單:

這樣,saveupload標簽就會自動檢測權限,並按科室中定義的管理組允許其中的成員上載,上載到科室下的upload目錄中的用戶名稱建立的專用目錄中,而存盤的文件名使用theimg名稱供客戶端嵌進正在編輯的文本中。

這樣,上載就真正成?一個可以自由方便地使用的組件了。

http://blog.csdn.net/zwwwxy/archive/2005/04/11/343545.aspx

http://zwwwxy.blogchina.com/672335.html
http://javaxml.blog-city.com/jsp.htm



可以使用多個jsp定制標簽在JSP中達到接近servelt的處理效果

jsp可以令菜鳥直接寫簡單的網頁程序(網友言),而servlet卻有jsp所不及的集成程度和易維護性。兩者在JAVA/BS系統中無法簡單取代,但 同時並存卻令開發者陷入近兩年來最常見的陷阱中:必須在一個即使是相對簡單的項目中維持多套程序模式的方案,顯然,這是高成本的。本文考慮並初步實驗了使 用標簽組件連續完成類似servlet的處理效果,從而達到魚和熊掌兼得的目的,看來有一定的效果。


在完全使用servlet的環境中,可以使用servlet的繼承獲得上級servlet的設定屬性;還可以使用servlet-chains達到分類處 理的目的,整個WEB程序與實際應用系統非常相似,高效而簡潔;在servlet-jsp的環境中servlet起到集中處理請求的作用,而jsp負責顯 示各種形式采摘的數據。後者最麻煩的就是在servlet/jsp中的數徑和變量處理方式不一致,平添大量的原始的工作量。strutsr actionmapping一定程度上解決這個問題,不過解決得不算太徹底。因此在大型的java BS應用中采用servlet/jsp形式所帶來的方便,一定程度上將會被這種變量的不一致性所抵消,畢竟,維持兩種處理方案本身就是高成本的。

因?這個原因,過去本人幹脆完全采用servlet形式,而通過另外寫程序解釋由網頁人員編寫的嵌套式的html來達到與JSP類似的目的。這套方案在三 四年前是有效的,但在今天由于SUN選擇了JSP作?發展的主體,包括JTL,TAG技術,甚至于jsdk1。5中的cacheResutlSet都是? 了這種(我認?是落後的)JSP隨機編碼而開發,因此,獨自堅持走servlet道路是不明智的,(參看本人《選擇JSP作?BS發展方向很可能是致命的 戰略失誤》一文);但是,同樣的疑問並不會因?SUN選擇了JSP而消失:如果完全采用JSP,那?在數據提交處理上還是必須使用SERVLET以簡化處 理邏輯,但同時也必須承受上述的負面作用。

作?SUN贊助支持的JAVA/BS主體項目方案之一的struts框架充分體現了這一矛盾帶來的困惑和折衷:struts- action/actionmapping本身就是?了達到克服上述的JSP不足,希望魚和熊掌兼得,通過ActionServlet令使用者減少 servelt程序的編寫量;不過,在不能完全解決問題的同時,也令開發者?了這不是主體需求的需求,而必須多采用一個框架;一定程度上實際上是得不嘗失。

如果上述邏輯成立,那?如同幾年前本人完全選擇servlet一樣,既然選擇了jsp作?主體方案,那?就應該考慮完全?棄servelt,以便以一套方 案處理項目,避免維護兩套系統帶來的附加性成本。但是如同所有人在若幹年前指出的一樣,JSP缺乏有效的代碼管理手段;也不便于形成象servlet那樣 的基本框架體系,這樣它與簡單的網頁程序如ASP/PHP沒有什?不一樣。引入javabean(組件,不是簡單的數據對象化載體),可以一定程度上改善 這種處境,但javabean缺乏統一的調用規範,卻令這樣的JSP比純粹的servelt開發顯得更?麻煩。

我在使用tag時,覺得可以吸取servelt-chains的概念,使用象SimpleTabSupport這樣最簡單的標簽方式,生成一個個的命令形 式的標簽,參數可以直接作?標簽參數輸入,這樣在某個jsp中次第引入這種標簽命令,就可以達到類似于servlet-chains的效果,而從易于配置 使用上看,超過了servelt。?簡便起見,我以struts的ActionServlet?藍本,寫成一個ActionTag的基本類,同樣使用 ActionErrors/ActionForm作?數據和消息的載體;然後所有的Command標簽全部繼承這個ActionTag,這樣編寫一個命令 標簽的工作量不會比編寫一個struts-action bean的工作量更大。另一方面,由于標簽直接可以接受參數設定,所以無需任何如Actionmappin這樣的預設置,實際上簡化了維護。我認?僅此而 言,它至少比struts的ActionMapping要簡潔有效。

類似這樣的在一個平面上以標簽形式執行多個命令的處理方法並不鮮見,大名昭昭的Apache的httpd.conf就是使用這樣的方式完成設置的。

通過這樣的方法,可以統一以JSP的方式來處理幾乎所有BS的網頁請求,接受在JSP頁面上的目錄和變量的同樣設定,估計可以大幅度降低開發和維護的成本,以及降低相應的技術要求。

http://zwwwxy.blogchina.com/603990.html

http://javaxml.blog-city.com/jspjspservelt.htm

最終還是手工輸出XML對象可靠

和xml打交道,常常是哭笑不得:我?什?要花那?大力氣和整個XML文檔打交通呢?實實在在的,我只不過想存取其中一個對象的屬性罷了!!前段時間了解 了castor覺得這是一個解決方案,不過也還是需要整個文檔的讀寫更新。一來是時間限制不允許當前深入研究,而且那也是一個不算成熟的項目;二來呢,采 納的話會和現在的digester讀取模式發生沖突,有點劃不過來。但是象科室設置的更新頻率看來越來越高,再放到XML中只讀靠手工改看來是不行的。因 此打算把科室對象移植進數據庫,但一動手就發現同樣有不劃算的地方。


事實上是發現忽視了一個問題,其實也是XML和關系數據庫存儲實質的一個對比內容:XML周邊存取的手段的確不是非常成熟,但是它是以對象的層次結構存儲 數據的,而關系數據庫則是平面形式地存儲。我目前打算使用secion轉?關系數據庫,目的是?了可以分科室的更改設置更方便,這在XML是一個文件,而 到了關系數據庫,卻是整個的一堆的關系表(關系概念中同樣是一個實體,但此實體非彼實體,它意味著反應一個對象的一堆表),而且要與象表類等進行關聯,相 當複雜的。當前這也許不是一個好主意,而且,在大項目中使用複雜的關系結構表達數量不多的記錄,似乎是一種成本效益比很低的過時的方法。所以,我猶豫了。

另一個辦法是做一個可更新的xml模件:處理手法包括:

1、修改SectionBase,使它是針對多個科室的多個xml工作,而不是象現在那樣一切解釋把所有的科室讀進去;

2、做一個更新各個科室的xml的方法;無論是casto的,還是其他什?方法的;

3、做一個更新各個科室的界面,把它連到科室管理台。

這?的關鍵是第二步。?確認第二步能夠以當前最簡單的方法完成,再次翻看先前下載的關于castor的文章,不過博客中國真是越來越弱不禁風,居然好久還 動不了,過好長時間才把原來的文章打開再讀一篇。研讀結果仍是一樣的,如果采用castor就意味著要采用它的JDO,而不僅僅是XML的輸出,而目前我 的讀入主要是使用digester;所以這?包含著更大範圍的修改,而且包含著更大不定性的試用;這也是我上兩個星期暫時放開castor的原因:目前沒 有時間深入研究它的使用思想和實際應用。看來,只能采用原始點的SAX或甚至字符串處理了。

再考慮一下常用的sax/xalan/jaxp/jdom幾種處理手法,如果不是單純對著非對象化的文檔內容工作,就是需要寫一個XSLT/和轉換器,而 無論如何,要與一貫的JAVA對象/XML對象匹配的模式一起工作,還必須做到讓上面的這些文檔對象可以與digester後的JAVA對象互換的方法: 沒聽說過!!從digester都沒有幾個人真的用過的情況下,我看就算上論壇問那幾個國內國外的老兄都是白問。我想這種方法如果有,一定就在 Digester的具體使用中,從jdom中獲得對象,以及重新轉?document對象——不過,沒有!!

看來,我要考慮一下自已實現的難道和可重用性是怎?樣的。......一想下來,其實這也不是什?難事,只需要在每個類那?實現一個接口,比如說 write,然後逐級調用不就搞惦了??何必舍近求遠,找些不可靠的東西試用呢?一通百通,實際上手工輸出對象字符串一點都不是一件恐怖的事,我是讓那些 文章作者給唬住了,關鍵就在于這是按對象輸出,程序量並不算大,而且也是挺好管理的。相比寫servlet輸出,小意思啦。


原始的方法不見得就是落後的,合適就行!

http://zwwwxy.blogchina.com/501600.html

http://blog.csdn.net/zwwwxy/archive/2005/03/30/333829.aspx
http://javaxml.blog-city.com/xml.htm

在Unix/Linux上令(java)JVM支持中文輸出

一、在Unix/Linux上令JVM支持中文輸出

如果用戶使用的是UNIX的遠程服務器,就會遇到中文字體在圖像中輸出的問題,特別是由于許多管理員並不喜歡把主機的locale定?zh(因?意味著可 能出亂碼或必須裝微形圖形終端象zhcon,但很多情況下這樣的條件並不具備)。大部分程序員的JAVA經驗苟限于JSP腳本程序,部分熟練的程序員大概 開發過中間件、servlet、applet或在WINDOWS上運行的GUI程序。如果開發的jfreechart是使用WINDOWS作?主機運行的 話,可以略過這一段,但如果使用的是UNIX類型的服務器的話,就常常遇到意想不到的中文顯示困難,甚至還未到輸出中文字體的階段,程序就報告 display異常錯誤。原因就在于,JAVA awt原來是針對(X)windows GUI編寫的程序,它常常需要使用display 1:0的設置設定顯示方式,在服務器模式下(象jsp或servlet),根本就不會有XWindowns運行,這時就會在許多程序中引起can not got display setting to 0:0的錯誤,包括jfreechart。解決辦法是在JVM?動中增加-Djava.awt.headless=true的設置。但這樣又帶來另一個問 題,會令使用象frame.getImage()方法的代碼中引起headless Exception,導致程序中止,而使用ImageBuffer的程序就不會受到影響。

象jfreechart這樣基于java awt,java Swing, java 2D API和程序應用到Linux/UNIX上,中文字體的輸出是一個必須解決的問題,否則連jfreereport都不能使用了。servlet也會碰到類 似的問題,但解決方式顯得相對簡單,servlet package已經內置了解決辦法,一般情況下,在 servlet?頭設兩句:

response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");

中文亂碼就不得存在。與簡單的jsp/servlet字符集轉換相比,這個問題要複雜得多,甚至比一般的linux中文化還要複雜。在正常情況下, jre只包含少數幾種字體(Font),但可以從X 系統,象windows獲得喜歡的字體支持;因此,如果開發者和使用者是在中文WINDOWS系統上開發,大概不會發覺問題的存在。但一旦當程序發布到 UNIX/Linux系統上後,就會發現圖形中的中文字符成?一個個的問號或者小方框。而此時,象jsp/servlet這樣的程序在客戶端的顯示卻是完 全正常的。一般情況下,JAVA默認情況下是使用en_OTF-8,或者ISO_8859_1讀入字符串,因此,象JSP通常使用從8859_1強制轉型 ?gb3312/GBK,就可以正常顯示中文,但是在上述的情形下,這種強制轉型地是完全無效的。?什?呢?如果程序員的系統概念是清晰的話,就會明白, JSP/SERVLET的字符串輸出,只是輸出字型,然後由客戶端(一般是?覽器)在客戶端桌面重整字型,用的是客戶端的字體,而相反, JfreeChart這樣的圖形程序輸出的是一個圖像,用的是服務器端jre的字體,與Xwindows的字體也無關。當系統本身不帶有字型時 (font),這正是服務器所常見的,就只能向jre添加支持中文的字體(font)才能根本上解決這個問題。

Jre的字體設置原理與Xwindows相似,並延用相同的工具,事實上,二進制字體文件延用相同的標准,各個公司間的字體集,象聯想、方正、微軟以及 linux Xwindows下是相同的,完全可以互相拷貝,僅僅是讀取字體的方式流程和設置方式稍有區別。目錄提及linux漢化的文章,其中主要就是增加中文字體 的支持,很多是廢話連篇,不知其所以然亂撞一通後驚呼"搞定啦"這樣不可重複的形式。所以這?先複習一下,然後和JRE的設置對照,原理就會顯得比較清 晰。目前linux的字體有兩處使用,一是linux console下的字體,二是Xwin等應用程序的字體,包括象zhcon這樣的?console程序。每處應用字體的程序都可以有自已的字體設置目錄; 但隨著Linux集成程度的強化,都傾向向通過默認的unixsocket7000端口調用xfs的字體服務。因此,字體設置只需對xfs進行設置就可以 完成。一些文章聲稱要停掉XFS,實際上毫無必要;xfs的調用僅僅是作?一個在XFConfig中的FontPath選項,作?另一個添加字體的方法, 就是直接把包含字體的目錄添加到FontPath,然後手工執行ttmkfdir——恰恰這本來是xfs設計代替您去做的。用戶實際上需要做的,要?是直 接在圖形工具中把字體文件添加到fonts:\\\中,或者是手工把字體文件加到xfs的目錄下的對應locale的目錄中,一般是在 /usr/share/lib/fonts/zh_CN/TrueType,重?xfs就搞定了。作?手工添加到XFConfig中的目錄,在XWin 中,簡單地說,字體位圖文件是通用的,包括對JRE,放在某一個目錄中,用戶需要做的就是通知XWIN這些目錄在什?地方,設置的位置就在 /etc/X11/XConfig的FontPath項。運行ttmkfdir命令生成fonts.dir文件,實際上都是字體調用的對照表,另外用戶可 以編輯fonts.alias這樣的文件,目的就是讓字體有個易記的名字。因此,字體的安裝關鍵在于字體位圖文件(拷到某個目錄),對照文件(由 ttmkfdir命令生成),和字體別名設置,所不同的是,在Xwin中這些由xfs自動完成,在jre中,就要開發者自已手工完成。

就Jre而言,字體位圖目錄是固定的,在$JRE_HOME/lib/fonts目錄中;fonts.dir*的目錄對照表文件也是一樣的,同樣是由 ttmkdir程序生成,而相當于別名等設置的文件,集中在$JRE_HOME/lib目錄下的*font.properties*"文件中定義。如果 JVM能直接支持中文輸出,那?就要求*font.properties*屬性文件中指示的字體型本身是支持中文的(換言之,JSDK自帶的字體文件是不 支持中文的)。按http://java.sun.com/j2se/1.3/docs/guide/intl/fontprop.html的說明, JVM按以下順序搜索字體屬性文件,尖括號是JVM檢測的系統屬性:

font.properties.__.
font.properties.__
font.properties._.
font.properties._
font.properties._.
font.properties._
font.properties._
font.properties.
font.properties..
font.properties.
font.properties.
font.properties


但在大多數情況下,實際上只需要面向一個font.properties文件。重新編一個font.properties文件是一項艱苦的工程,幸好在 Linux中有一個font.properties.zh.Turbo,本來是面向TurboLinux用戶,不過在大多數情況下可以基于它修改。把這個 文件重命名?font.properties,覆蓋掉原來的文件,但系統這時仍不支持中文,查看一下,就會發現 font.properties.zh.Turbo文件中的"-tlc-song-medium-r-normal--*-%d-*-*-c-*-gbk -0"字型在fonts.dir對照表中並不具備,這種字型包含在TurboLinux的系統字型庫中。下面的方法有兩個,一是安裝這種字體,二是更改另 一種字體型庫並重新指定。TurboLinux的字體安裝文件名字是ttf-zh-song*rpm,在互聯網上可以找到,安裝後把 /usr/lib/X11/fonts/tt下的ttf文件拷貝到$JRE_HOME/lib/fonts目錄下,重新生成fonts.dir文件。第二 種辦法就是重找字體庫,微軟WINDOWS上的fonts目錄下的ttf文件一般可用,但更全的是從http: //www.microsoft.com/china/windows2000/downloads/18030.asp 下載它的字符集文件,安裝後把ttf拷到JRE的fonts目錄下;另外, XWin如果支持中文的話,可以從/usr/lib/X11/fonts/TrueType下找到一兩個支持中文的字體文件。

把這些文件統統拷到JRE的fonts目錄並不能令JVM立刻支持中文,回想一下前面提到的,在font.properties中指定的文字類型,必須有 一個對照表fonts.dir指示JVM如何把用戶調用的font類型匹配到相應的字型文件上。因此,運行ttmkfdir > fonts.dir生成新的對照表。用Vi打開這個文件,最上面的數字是系統可以調用的字型數目,下面的屬性值對左側就是物理字型名稱,右側是它的編號, 這就是用到font.properties 文件中指明使用的編號(包含了設置,左側的就是字符的別名,即虛擬字型),區別僅僅是把0-0-0c-0這類設置中的某幾項改作通配符和%d接受調用參數 而已,不改也行,大不了輸出的字難看一點(反正我不是美工,不太關心)。用可用的字型編號代替了font.properties中無效的字型設置後,理論 上似乎JVM已經支持中文了,但在實際操作上,仍是經常見到問號、空格之類,原因就在于JAVA對中文的支持不但與運行環境有關,還與編譯參數有關,如果 類文件不是以gb2312/encoding編譯的話,等同于讀入是OTF-8/8859_1,這時再轉換也沒有用了,因此,如果是drawString 之類的,必須切記使用(-encoding gb2312);當然,如果操作系統本身已經是中文的話,這條就由編譯器自動采納了。
http://blog.csdn.net/zwwwxy/archive/2005/03/29/333441.aspx
http://zwwwxy.blogchina.com/294399.html
http://javaxml.blog-city.com/unixlinuxjavajvm.htm
http://javaxml.blog-city.com/jfreechart.htm

JAVAFREECHART對象關系

jfreechart是一個優秀的開源JAVA 2D項目,缺點是缺乏文檔,中英文都是如此。本文是經驗總結的第二部分

二、jfreechart作圖類對象的協調關系

jfreechart的繪圖對象由一個org.jfree.chart.JFreeChart組成,但作?繪圖關鍵的Graphich2d通過 org.jfree.chart.render.*中的對應render類包裝後設入,換言之,開發者可以通過對基礎圖板Graphic的設置,完成必要 的繪圖預定效果設計;而大多數的修改,實際上可以通過包裝的各個類操作而不用直接修改Graphic對象屬性(誰記得呢?)。jfreechart的數據 接口由org.jfree.chart.plot.*中的不同的plot包裝,與之相對應的是不同的dataset,位于 org.jfree.chart.data.*中不同的dataset接口包裝。使用jfreechart作圖的關鍵在于生一個個相應的數據集對象,,然 後包裝成對應的一個個繪圖集plot對象,最後再包裝成不同的JFreeChart對象交付輸出。通過new方法可以一步步完成上面的步驟。換言之, plot類是圖形的設計,render 是繪制的工具,而dataset則是填充的數據;這樣就把作圖的三個關鍵因素分別抽象成統一的接口,互想搭配出各種圖形。對于可能有多套數據集的圖表,如 時間序列的多條曲線走勢圖(象幾只股票),傳入plot的不是數據集,而是數據集的集合,一般命名?某某collection。

通過ChartFactory的不同方法生成不同的Chart類型,可以相應地縮小了由dataset對不同的chart對象的操作過程代碼量,直接獲得 chart對象。實際上是由工廠類代替用戶生成必要的render和plot類,如果用戶不想使用默認的設置,就需要再通過get方法得出相應的plot 對象進行修改。jfreechart的最後圖像輸出一般由org.jfree.chart.ChartUtilites完成,這個類可以向接定的 PrintWriter對象輸出完成的Chart對象。在服務器程序中,另一個ServerUtilites方法調用了這個方法,生成一個圖像臨時文件, 並向JSP或servlet返回這個文件對象,通過把這個圖像的生命周期與session綁定,希望可以實現緩沖功能,降低服務器動態生成圖像的損耗。但 是也有很大的問題其一就是如果session很長,就等于不能生成實時圖像,其二就是訪問的人多了,服務器的負擔似乎反而加大了。這個算法顯然有問題,倒 不如修改成按時間更新一個圖像更?合適。

觀察代碼,兩者效果是一樣的:

A、工廠方法:

JFreeChart chart = ChartFactory.createPieChart3D( "2000 GDP分布比例圖", data, true, false, false );//指定獲得不同的實現chart對象,含有不同的plot繪圖對象

PiePlot plot = (PiePlot) chart.getPlot();//獲取plot對象用于修訂屬性,強制造型,以便調用各自的方法
plot.setLabelGenerator(new StandardPieItemLabelGenerator( "{0} = {2}", NumberFormat.getNumberInstance(), NumberFormat.getPercentInstance() ));//設定注釋方式
plot.setForegroundAlpha(0.5f);//設定透明度
plot.setNoDataMessage("無記錄內容");//無記錄異常顯示

B、手工生成對象

PiePlot plot = new PiePlot(dataset);

plot.setLabelGenerator(new StandardPieItemLabelGenerator( "{0} = {2}", NumberFormat.getNumberInstance(), NumberFormat.getPercentInstance() ));//設定注釋方式
plot.setForegroundAlpha(0.5f);//設定透明度
plot.setNoDataMessage("無記錄內容");//無記錄異常顯示

JFreeChart chart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, plot, false);