欧美最新另类人妖,欧美色图天堂,日韩香蕉视频http://www.aygfsteel.com/isoft/感悟人生,領悟世界,創造生活,創新社會zh-cnMon, 28 Jul 2025 06:45:45 GMTMon, 28 Jul 2025 06:45:45 GMT60J2EE架構的最佳實踐http://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html夢幻流星夢幻流星Thu, 03 Jan 2008 06:25:00 GMThttp://www.aygfsteel.com/isoft/archive/2008/01/03/172475.htmlhttp://www.aygfsteel.com/isoft/comments/172475.htmlhttp://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html#Feedback0http://www.aygfsteel.com/isoft/comments/commentRss/172475.htmlhttp://www.aygfsteel.com/isoft/services/trackbacks/172475.html   首先,本文的目標讀者是正在從事技術工作的架構師。為了避免浪費大家的才智,我會避免講述一些陳腐的最佳實踐,例如“日常構建(build daily)”、“測試一切(test everything)”和“經常集成( integrate often)。 任何具有稱職架構師的項目都有分工明確的、定義良好的團隊結構。他們還為進行編碼檢查、構建代碼(每日或在需要時)、進行測試(單元、集成和系統的)、部署和配置/釋放管理而具備已記錄的過程。
  其次,我將跳過通常吹捧的最佳實踐,例如“基于接口的設計”、“使用著名的設計模型”以及“使用面向服務的架構”等。相反,我將集中講述我曾學過并且使用了若干年的6(不是很多)個方面的in-the-trench課程。最后,本文的目的是讓您思考一下自己的架構,提供工作代碼示例或者解決方案超出了本文的范圍。下面就讓我介紹一下這6課:
1、切勿繞過服務器端驗證
2、安全并非是附加物
3、國際化(I18N)不再是紙上談兵
4、在MVC表示中避免共同的錯誤
5、不要被POJO束縛住手腳
6、數據訪問并不能托管O/R映射


第1課:切勿繞過服務器端驗證
  作為一位軟件顧問,我曾有機會不但設計并實現了Web應用程序,而且還評估/審核了許多Web應用程序。在復雜的、并且用JavaScript客戶端封裝的應用程序內,我經常遇到對用戶輸入信息執行大量檢查的Web頁面。即使HTML元素具有數據有效性的屬性也如此,例如MAXLENGTH。只有在成功驗證所有輸入信息后,才能提交HTML表單。結果,一旦服務器端收到通知表單(請求),便恰當地執行業務邏輯。
  在此,您發現問題了么?開發人員已經做了許多重要的假設。例如,他們假設所有的Web應用程序用戶都同樣誠實。開發人員還假設所有用戶將總是使用他們測試過的瀏覽器訪問Web應用程序。還有很多其他的假設。這些開發人員忘記了利用可以免費得到的工具,通過命令行很容易地模擬類似瀏覽器的行為。事實上,通過在瀏覽器窗口中鍵入適當的URL,您可以發送任何“posted”表單,盡管如此,通過禁用這些頁面的GET請求,您很容易地阻止這樣的“表單發送”。但是,您不能阻止人們模擬甚至創建他們自己的瀏覽器來入侵您的系統。
根本的問題在于開發人員不能確定客戶端驗證與服務器端驗證的主要差別。兩者的主要差別不在于驗證究竟發生在哪里,例如在客戶端或者在服務器端。主要的差別在于驗證背后的目的不同。
  客戶端驗證僅僅是方便。執行它可為用戶提供快速反饋??使應用程序似乎做出響應,給人一種運行桌面應用程序的錯覺。
  另一方面,服務器端驗證是構建安全Web應用程序必需的。不管在客戶端一側輸入的是什么,它可以確保客戶端送往服務器的所有數據都是有效的。
  因而,只有服務器端驗證才可以提供真正應用程序級的安全。許多開發人員陷入了錯誤感覺的圈套:只有在客戶端進行所有數據的驗證才能確保安全。下面是說明此觀點的一個常見的示例:
  一個典型的登錄頁面擁有一個用來輸入用戶名的文本框和一個輸入密碼的文本框。在服務器端,某人在接收servlet中可能遇到一些代碼,這些代碼構成了下面形式的SQL查詢:
"SELECT * FROM SecurityTable WHERE username = @#" + form.getParameter("username") + "@# AND password = @#" + form.getParameter("password") + "@#;",并執行這些代碼。如果查詢在結果集的某一行返回,則用戶登錄成功,否則用戶登錄失敗。
  第一個問題是構造SQL的方式,但現在讓我們暫時忽略它。如果用戶在用戶名中輸入“Alice@#--”會怎樣呢?假設名為“Alice”的用戶已經在SecurityTable中,這時此用戶(更恰當的說法是黑客)成功地登錄。我將把找出為什么會出現這種情況的原因做為留給您的一道習題。
  許多創造性的客戶端驗證可以阻止一般的用戶從瀏覽器中這樣登錄。但對于已經禁用了JavaScript的客戶端,或者那些能夠使用其他類似瀏覽器程序直接發送命令(HTTP POST和GET命令)的高級用戶(或者說黑客)來說,我們又有什么辦法呢?服務器端驗證是防止這種漏洞類型所必須的。這時,SSL、防火墻等都派不上用場了。

第2課:安全并非是附加物
  如第1課所述,我曾有幸研究過許多Web應用程序。我發現所有的JavaServer Page(JSP)都有一個共同的主題,那就是具有類似下面偽代碼的布局:

<%
User user =
session.getAttribute("User");
if(user == null)
{
// redirect to
// the logon page…
}
if(!user.role.equals("manager"))
{
// redirect to the
// "unauthorized" page…
}
%>

<!-
HTML, JavaScript, and JSP
code to display data and
allow user interaction -->

  如果項目使用諸如Struts這樣的MVC框架,所有的Action Bean都會具有類似的代碼。盡管最后這些代碼可能運行得很好,但如果您發現一個bug,或者您必須添加一個新的角色(例如,“guest”或者“admin”),這就會代表一場維護惡夢。
  此外,所有的開發人員,不管您多年輕,都需要熟悉這種編碼模式。當然,您可以用一些JSP標簽來整理JSP代碼,可以創建一個清除派生Action Bean的基本Action Bean。盡管如此,由于與安全相關的代碼會分布到多個地方,所以維護時的惡夢仍舊存在。由于Web應用程序的安全是強迫建立在應用程序代碼的級別上(由多個開發人員),而不是建立在架構級別上,所以Web應用程序還是很可能存在弱點。
  很可能,根本的問題是在項目接近完成時才處理安全性問題。最近作為一名架構師,我曾在一年多的時間里親歷了某一要實現項目的6個版本,而直到第四版時我們才提到了安全性??即使該項目會將高度敏感的個人數據暴露于Web上,我們也沒有注意到安全性。為了更改發布計劃,我們卷入了與項目資助人及其管理人員的爭斗中,以便在第一版中包含所有與安全相關的功能,并將一些“業務”功能放在后續的版本中。最終,我們贏得了勝利。而且由于應用程序的安全性相當高,能夠保護客戶的私有數據,這一點我們引以為榮,我們的客戶也非常高興。
  遺憾的是,在大多數應用程序中,安全性看起來并未增加任何實際的商業價值,所以直到最后才解決。發生這種情況時,人們才匆忙開發與安全相關的代碼,而絲毫沒有考慮解決方案的長期可維護性或者健壯性。忽視該安全性的另一個征兆是缺乏全面的服務器端驗證,如我在第1課中所述,這一點是安全Web應用程序的一個重要組成部分。
  記住:J2EE Web應用程序的安全性并非僅僅是在Web.xml 和ejb-jar.xml文件中使用合適的聲明,也不是使用J2EE技術,如Java 認證和授權服務(Java Authentication and Authorization Service,JAAS)。而是經過深思熟慮后的設計,且實現一個支持它的架構。

第3課:國際化(I18N)不再是紙上談兵
  當今世界的事實是許多英語非母語的人們將訪問您的公共Web應用程序。隨著電子政務的實行,由于它允許人們(某個國家的居民)在線與政府機構交互,所以這一點特別真實。這樣的例子包括換發駕照或者車輛登記證。許多第一語言不是英語的人們很可能將訪問這樣的應用程序。國際化(即:“i18n”,因為在“internationalization”這個單詞中,字母i和字母n之間一共有18個字母)使得您的應用程序能夠支持多種語言。
  顯然,如果您的JSP 頁面中有硬編碼的文本,或者您的Java代碼返回硬編碼的錯誤消息,那么您要花費很多時間開發此Web應用程序的西班牙語版本。然而,在Web應用程序中,為了支持多種語言,文本不是惟一必須“具體化”的部分。因為許多圖像中嵌有文字,所以圖形和圖像也應該是可配置的。在極端的情況下,圖像(或者顏色)在不同的文化背景中可能有完全不同的意思。類似地,任何格式化數字和日期的Java代碼也必須本地化。但問題是:您的頁面布局可能也需要更改。
  例如,如果您使用HTML表格來格式化和顯示菜單選項、應用程序題頭或注腳,則您可能必須為每一種支持的語言更改每一欄的最小寬度和表格其他可能的方面。為了適應不同的字體和顏色,您可能必須為每一種語言使用單獨的樣式表。
  顯然,現在創建一個國際化的Web應用程序面臨的是架構挑戰而不是應用程序方面的挑戰。一個架構良好的Web應用程序意味著您的JSP頁面和所有與業務相關的(應用程序特有的)Java代碼都不知不覺地選擇了本地化。要記住的教訓是:不要因為Java、J2EE支持國際化而不考慮國際化。您必須從第一天起就記住設計具有國際化的解決方案。

第4課:在MVC表示中避免共同的錯誤
  J2EE開發已經足夠成熟,在表示層,大多數項目使用MVC架構的某些形式,例如Struts。在這樣的項目中,我常見到的現象是對MVC模式的誤用。下面是幾個示例。
  常見的誤用是在模型層(例如,在Struts的Action Bean中)實現了所有的業務邏輯。不要忘了,表示層的模型層仍然是表示層的一部分。使用該模型層的正確方法是調用適當的業務層服務(或對象)并將結果發送到視圖層(view layer)。用設計模式術語來說,MVC表示層的模型應該作為業務層的外觀(Fa?ade)來實現。更好的方法是,使用核心J2EE模式(Core J2EE Patterns)中論述到的Business Delegate模式。這段自書中摘錄的內容精彩地概述了將您的模型作為Business Delegate來實現的要點和優點:
  Business Delegate起到客戶端業務抽象化的作用。它抽象化,進而隱藏業務服務的實現。使用Business Delegate,可以降低表示層客戶端和系統的業務服務.之間的耦合程度。根據實現策略不同,Business Delegate可以在業務服務API的實現中,保護客戶端不受可能的變動性影響。這樣,在業務服務API或其底層實現變化時,可以潛在地減少必須修改表示層客戶端代碼的次數。
  另一個常見的錯誤是在模型層中放置許多表示類型的邏輯。例如,如果JSP頁面需要以指定方式格式化的日期或者以指定方式排序的數據,某些人可能將該邏輯放置在模型層,對該邏輯來說,這是錯誤的地方。實際上,它應該在JSP頁面使用的一組helper類中。當業務層返回數據時,Action Bean應該將數據轉發給視圖層。這樣,無需創建模型和視圖之間多余的耦合,就能夠靈活支持多個視圖層(JSP、Velocity、XML等)。也使視圖能夠確定向用戶顯示數據的最佳方式。
  最后,我見過的大多數MVC應用程序都有未充分應用的控制器。例如,絕大多數的Struts應用程序將創建一個基本的Action類,并完成所有與安全相關的功能。其他所有的Action Bean都是此基類的派生類。這種功能應該是控制器的一部分,因為如果沒有滿足安全條件,則首先調用不應該到達Action Bean(即:模型)。記住,一個設計良好的MVC架構的最強大功能之一是存在一個健壯的、可擴展的控制器。您應該利用該能力以加強自己的優勢。

第5課:不要被POJO束縛住手腳
  我曾目睹許多項目為了使用Enterprise JavaBean而使用Enterprise JavaBean。因為EJB似乎給項目帶來優越感和妄自尊大的表現,所以有時它是顯酷的要素(coolness factor)。而其他時候,它會使J2EE和EJB引起混淆。記住,J2EE和EJB不是同意詞。EJB只是J2EE 的一部分,J2EE 是包含JSP、servlet、Java 消息服務(JMS)、Java數據庫連接(JDBC)、JAAS、 Java管理擴展(JMX)和EJB在內的一系列技術,同樣也是有關如何共同使用這些技術建立解決方案的一組指導原則和模式。
  如果在不需要使用EJB的情況下使用EJB,它們可能會影響程序的性能。與老的Web服務器相比,EJB一般對應用服務器有更多的需求。EJB提供的所有增值服務一般需要消耗更大的內存和更多的CPU時間。許多應用程序不需要這些服務,因此應用服務器要與應用程序爭奪資源。
  在某些情況下,不必要地使用EJB可能使應用程序崩潰。例如,最近我遇到了一個在開源應用服務器上開發的應用程序。業務邏輯封裝在一系列有狀態會話bean(EJB)中。開發人員為了在應用服務器中完全禁用這些bean的“鈍化”費了很大的勁。客戶端要求應用程序部署在某一商用應用服務器上,而該服務器是客戶端技術棧的一部分。該應用服務器卻不允許關閉“鈍化”功能。事實上,客戶端不想改變與其合作的應用服務器的設任何置。結果,開發商碰到了很大的麻煩。(似乎)有趣的事情是開發商自己都不能給出為什么將代碼用EJB(而且還是有狀態會話bean)實現的好理由。不僅僅是開發商會遇到性能問題,他們的程序在客戶那里也無法工作。
  在Web應用程序中,無格式普通Java 對象(POJO)是EJB強有力的競爭者。POJO是輕量級的,不像EJB那樣負擔額外的負擔。在我看來,對許多EJB的優點,例如對象入池,估計過高。POJO是您的朋友,不要被它束縛住手腳。

第6課:數據訪問并不能托管O/R映射
  我曾參與過的所有Web應用程序都向用戶提供從其他地方存取的數據,并且因此需要一個數據訪問層。這并不是說所有的項目都需要標識并建立這樣一個層,這僅僅說明這樣層的存在不是隱含的就是明確的。如果是隱含的數據層,數據層是業務對象(即:業務服務)層的一部分。這適用于小型應用程序,但通常與大一些項目所接受的架構指導原則相抵觸。
  總之,數據訪問層必須滿足或超出以下四個標準:
  具有透明性
  業務對象在不知道數據源實現的具體細節情況下,可以使用數據源。由于實現細節隱藏在數據訪問層的內部,所以訪問是透明的。
  易于遷移
  數據訪問層使應用程序很容易遷移到其他數據庫實現。業務對象不了解底層的數據實現,所以遷移僅僅涉及到修改數據訪問層。進一步地說,如果您正在部署某種工廠策略,您可以為每個底層的存儲實現提供具體的工廠實現。如果是那樣的話,遷移到不同的存儲實現意味著為應用程序提供一個新的工廠實現。
  盡量減少業務對象中代碼復雜性
  因為數據訪問層管理著所有的數據訪問復雜性,所以它可以簡化業務對象和使用數據訪問層的其他數據客戶端的代碼。數據訪問層,而不是業務對象,含有許多與實現相關的代碼(例如SQL語句)。這樣給開發人員帶來了更高的效率、更好的可維護性、提高了代碼的可讀性等一系列好處。
  把所有的數據訪問集中在單獨的層上
  由于所有的數據訪問操作現在都委托給數據訪問層,所以您可以將這個單獨的數據訪問層看做能夠將應用程序的其他部分與數據訪問實現相互隔離的層。這種集中化可以使應用程序易于維護和管理。
  注意:這些標準都不能明確地調出對O/R(對象到關系)映射層的需求。O/R映射層一般用O/R映射工具創建,它提供對象對關系數據結構的查看和感知(look-and-feel)。在我看來,在項目中使用O/R映射與使用EJB類似。在大多數情況下,并不要求它。對于包含中等規模的聯合以及多對多關系的關系型數據庫來說,O/R映射會變得相當復雜。由于增加O/R 映射解決方案本身的內在復雜性,例如延遲加載(lazy loading)、高速緩沖等,您將為您的項目帶來更大的復雜性(和風險)。
  為了進一步支持我的觀點,我將指出按照Sun Microsystem所普及的實體Bean(O/R映射的一種實現)的許多失敗的嘗試,這是自1.0版以來一直折磨人的難題。在SUN的防衛措施中,一些早期的問題是有關EJB規范的開發商實現的。這依次證明了實體Bean規范自身的復雜性。結果,大多數J2EE架構師一般認為從實體Bean中脫離出來是一個好主意。
  大多數應用程序在處理他們的數據時,只能進行有限次數的查詢。在這樣的應用程序中,訪問數據的一種有效方法是實現一個數據訪問層,該層實現執行這些查詢的一系列服務(或對象、或API)。如上所述,在這種情況下,不需要O/R映射。當您要求查詢靈活性時,O/R映射正合適,但要記住:這種附加的靈活性并不是沒有代價的。
  就像我承諾的那樣,在本文中,我盡量避免陳腐的最佳實踐。相反,關于J2EE項目中每一位架構師必須做出的最重要的決定,我集中講解了我的觀點。最后,您應該記住:J2EE并非某種具體的技術,也不是強行加入到解決方案中的一些首字母縮寫。相反,您應該在適當的時機,恰當的地方,使用合適的技術,并遵循J2EE的指導原則和J2EE中所包含的比技術本身重要得多的實踐。


JAVA 12個最重要的J2EE最佳實踐

1、始終使用 MVC 框架。
2、在每一層都應用自動單元測試和測試管理。
3、按照規范來進行開發,而不是按照應用服務器來進行開發。
4、從一開始就計劃使用 J2EE 安全性。
5、創建您所知道的。
6、當使用 EJB 組件時,始終使用會話 Facades。
7、使用無狀態會話 bean,而不是有狀態會話 bean.
8、使用容器管理的事務。
9、將 JSP 作為表示層的首選。
10、當使用 HttpSession 時,盡量只將當前事務所需要的狀態保存其中,其他內容不要保存在 HttpSession 中。
11、在 WebSphere 中,啟動動態緩存,并使用 WebSphere servlet 緩存機制。
12、為了提高程序員的工作效率,將 CMP 實體 bean 作為 O/R 映射的首選解決方案。


1. 始終使用 MVC 框架。

MVC 框架可以將業務邏輯(Java beans 和 EJB 組件)、控制器邏輯(Servlets/Struts 動作)、表示層(JSP、XML/XSLT)清晰地分離開來。良好的分層可以帶來許多好處。

MVC 框架對于成功使用 J2EE 是如此重要,以致沒有其他最佳實踐可以與其相提并論。模型-視圖-控制器(MVC)是設計 J2EE 應用程序的基礎。MVC 將您的程序代碼簡單地劃分下面幾個部分:

負責業務邏輯的代碼(即模型——通常使用 EJB 或者普通的 Java 對象來實現)。

負責用戶界面顯示的代碼(即視圖——通常通過 JSP 及標記庫來實現,有時也使用 XML 和 XSLT 來實現)。

負責應用程序流程的代碼(即控制器——通常使用 Java Servlet 或像 Struts 控制器這樣的類來實現)。

如果您不遵循基本的 MVC 框架,在開發過程中就會出現許多的問題。最常見的問題就是在視圖部分添加了太多的成分,例如,可能存在使用 JSP 標記來執行數據庫訪問,或者在 JSP 中進行應用程序的流程控制,這在小規模的應用程序中是比較常見的,但是,隨著后期的開發,這樣做將會帶來問題,因為 JSP 逐步變得越來越難以維護和調試。

類似地,我們也經常看到將視圖層構建到業務邏輯的情況。例如,一個常見的問題就是將在構建視圖時使用的 XML 解析技術直接應用到業務層。業務層應該對業務對象——而不是綁定到視圖的特定數據表示進行操作。

然而,只是具有合適的組件并不一定意味著可以使您的應用程序得到合適的分層。我們常常見到一些應用程序包含 servlet、JSP 和 EJB 組件所有這三項,然而,其主要的業務邏輯卻是在 servlet 層實現的,或者應用程序導航是在 JSP 中處理的。您必須進行嚴格的代碼檢查并重構您的代碼,以確保應用程序的業務邏輯只在模型層(Model layer)進行處理,應用程序導航只通過控制器層(Controller layer)進行處理,而您的視圖(Views)只是將傳遞過來的模型對象以 HTML 及 JavaScript 的形式表示出來。


2. 在應用程序的每一層都使用自動單元測試和測試管理。

不要只是測試您的圖形用戶界面(GUI)。分層的測試使測試及維護工作變得極其簡單。

在過去的幾年中,在方法學領域有了相當大的革新,例如新出現的被稱為 Agile(例如 SCRUM [Schwaber] 和極限編程 [Beck1])的輕量級方法現在已經得到了很普遍的應用。幾乎所有的這些方法中的一個共同的特征是它們都提倡使用自動的測試工具,這些工具可以幫助開發人員用更少的時間進行回歸測試 (regression testing),并可以幫助他們避免由于不充分的回歸測試造成的錯誤,因此可以用來提高程序員的工作效率。實際上,還有一種被稱為 Test-First Development [Beck2] 的方法,這種方法甚至提倡在開發實際的代碼之前就先編寫單元測試。然而,在您測試代碼之前,您需要將代碼分割成一些可測試的片斷。一個“大泥球”是難以測試的,因為它不是只實現一個簡單的易于識別的功能。如果您的每個代碼片斷實現多個方面的功能,這樣的代碼將難以保證其完全的正確性。

MVC 框架(以及 J2EE 中的 MVC 實現)的一個優點就是元素的組件化能夠(實際上,相當的簡單)對您的應用程序進行單元測試。因此,您可以方便地對實體 bean、會話 bean 以及 JSP 獨立編寫測試用例,而不必考慮其他的代碼。現在有許多用于 J2EE 測試的框架和工具,這些框架及工具使得這一過程更加簡單。例如,JUnit(是一種由 junit.org 開發的開放源代碼工具)和 Cactus(由 Apache 開發的開放源代碼工具)對于測試 J2EE 組件都非常有用。[Hightower] 詳細探討了如何在 J2EE 中使用這些工具。

盡管所有這些詳述了怎樣徹底地測試您的應用程序,但是我們仍然看到一些人認為只要他們測試了 GUI(可能是基于 Web 的 GUI,或者是獨立的 Java 應用程序),則他們就全面地測試了整個應用程序。GUI 測試很難達到全面的測試,有以下幾種原因。首先,使用 GUI 測試很難徹底地測試到系統的每一條路徑,GUI 僅僅是影響系統的一種方式,可能存在后臺運算、腳本和各種各樣的其他訪問點,這也需要進行測試。然而,它們通常并不具有 GUI。第二,GUI 級的測試是一種非常粗粒度的測試。這種測試只是在宏觀水平上測試系統的行為。這意味著一旦發現存在問題,則與此問題相關的整個子系統都要進行檢查,這使得找出 bug(缺陷)將是非常困難的事情。第三,GUI 測試通常只有在整個開發周期的后期才能很好地得到測試,這是因為只有這那個時候 GUI 才得到完整的定義。這意味著只有在后期才可能發現潛在的 bug。第四,一般的開發人員可能沒有自動的 GUI 測試工具。因此,當一個開發人員對代碼進行更改時,沒有一種簡單的方法來重新測試受到影響的子系統。這實際上不利于進行良好的測試。如果開發人員具有自動的代碼級單元測試工具,開發人員就能夠很容易地運行這些工具以確保所做的更改不會破壞已經存在的功能。最后,如果添加了自動構建功能,則在自動構建過程中添加一個自動的單元測試工具是非常容易的事情。當完成這些設置以后,整個系統就可以有規律地進行重建,并且回歸測試幾乎不需要人的參與。

另外,我們必須強調,使用 EJB 和 Web 服務進行分布式的、基于組件的開發使得測試單個的組件變得非常必要。如果沒有“GUI”需要測試,您就必須進行低級(lower-level)測試。最好以這種方式開始測試,省得當您將分布式的組件或 Web 服務作為您的應用程序的一部分時,您不得不花費心思重新進行測試。

總之,通過使用自動的單元測試,能夠很快地發現系統的缺陷,并且也易于發現這些缺陷,使得測試工作變得更加系統化,因此整體的質量也得以提高。


3. 按照規范來進行開發,而不是按照應用服務器來進行開發。
要將規范熟記于心,如果要背離規范,要經過慎密的考慮后才可以這樣做。這是因為當您背離規則的時候,您所做的事情往往并不是您應該做的事情。

當您要背離 J2EE 可以允許您做的事情的時候,這很容易讓使您遭受不幸。我們發現有一些開發人員鉆研一些 J2EE 允許之外的東西,他們認為這樣做可以“稍微”改善J2EE的性能,而他們最終只會發現這樣做會引起嚴重的性能問題,或者在以后的移植(從一個廠商到另一個廠商,或者是更常見的從一個版本到另一個版本)中會出現問題。實際上,這種移植問題是如此嚴重,以致 [Beaton] 將此原則稱為移植工作的基本最佳實踐。

現在有好幾個地方如果不直接使用 J2EE 提供的方法肯定會產生問題。一個常見的例子就是開發人員通過使用 JAAS 模塊來替代 J2EE 安全性,而不是使用內置的遵循規范的應用程序服務器機制來進行驗證和授權。要注意不要脫離 J2EE 規范提供的驗證機制,如果脫離了此規范,這將是系統存在安全漏洞以及廠商兼容性問題的主要原因。類似地,要使用 servlet 和 EJB 規范提供的授權機制,并且如果您要偏離這些規范的話,要確保使用規范定義的 API(例如 getCallerPrincipal())作為實現的基礎。通過這種方式,您將能夠利用廠商提供的強安全性基礎設施,其中,業務要求需要支持復雜的授權規則。

其他常見的問題包括使用不遵循 J2EE 規范的持久性機制(這使得事務管理變得困難)、在J2EE程序中使用不適當的J2SE 方法(例如線程或 singleton),以及使用您自己的方法解決程序到程序(program-to-program)的通信,而不是使用 J2EE 內在支持的機制(例如 JCA、JMS 或 Web 服務)。當您將一個遵循 J2EE 的服務器移植到其他的服務器上,或者移植到相同服務器的新版本上,上述的設計選擇將會造成無數的問題。唯一要背離規范的情況是,當一個問題在規范的范圍內無法解決的時候。例如,安排執行定時的業務邏輯在 EJB2.1 出現之前是一個問題,在類似這樣的情況下,我們建議當有廠商提供的解決方案時就使用廠商提供的解決方案(例如 WebSphere Application Server Enterprise 中的 Scheduler 工具),而在沒有廠商提供的解決方案時就使用第三方提供的工具。如果使用廠商提供的解決方案,應用程序的維護以及將其移植到新的規范版本將是廠商的問題,而不是您的問題。

最后,要注意不要太早地采用新技術。太過于熱衷采用還沒有集成到 J2EE 規范的其他部分或者還沒有集成到廠商的產品中的技術常會帶來災難性的后果。支持是關鍵的——如果您的廠商不直接支持一種特定的在 JSR 中提出的技術,但此技術還沒有被 J2EE 所接受,那么您就不應該采用此技術。畢竟,我們中的大多數人從事解決業務問題,而不是推進技術的發展。


4. 從一開始就計劃使用 J2EE 安全性。

啟用 WebSphere 安全性。這使您的 EJB 和 URL 至少可以讓所有授權用戶訪問。不要問為什么——照著做就是了。

在與我們合作的客戶中,一開始就打算啟用 WebSphere J2EE 安全性的顧客是非常少的,這一點一直讓我們感到吃驚。據我們估計大約只有 50% 的顧客一開始就打算使用此特性。例如,我們曾與一些大型的金融機構(銀行、代理等等)合作過,他們也沒有打算啟用安全性。幸運的是,這種問題在部署之前的檢查時就得以解決.

不使用 J2EE 安全性是危險的事情。假設您的應用程序需要安全性(幾乎所有的應用程序都需要),您敢打賭您的開發人員能夠構建出自己的安全性系統,而這個系統比您從 J2EE 廠商那里買來的更好。這可不是個好的賭注,為分布式的應用程序提供安全性是異常困難的。例如,您需要使用網絡安全加密令牌控制對 EJB 的訪問。以我們的經驗看來,大多數自己構建的安全性系統是不安全的,并且有重大的缺陷,這使產品系統極其脆弱。

一些不使用 J2EE 安全性的理由包括:擔心性能的下降,相信其他的安全性(例如 Netegrity SiteMinder)可以取代 J2EE 安全性,或者是不知道 WebSphere Application Server 安全特性及功能。不要陷入這些陷阱之中,尤其是,盡管像 Netegrity SiteMinder 這樣的產品能夠提供優秀的安全特性,但是僅僅其自身不可能保護整個 J2EE 應用程序。這些產品必須與 J2EE 應用程序服務器聯合起來才可能全面地保護您的系統。

其他的一種常見的不使用 J2EE 安全性的原因是:基于角色的模型沒有提供足夠的粒度訪問控制以滿足復雜的業務規則。盡管事實是這樣的,但這也不應該成為不使用 J2EE 安全性的理由。相反地,應該將 J2EE 驗證及 J2EE 角色與特定的擴展規則結合起來。如果復雜的業務規則需要做出安全性決策,那就編寫相應的代碼,其安全性決策要基于可以直接使用的以及可靠的 J2EE 驗證信息(用戶 ID 和角色)。


5. 創建您所知道的。

反復的開發工作將使您能夠逐漸地掌握所有的 J2EE 模塊。要從創建小而簡單的模塊開始而不是從一開始就馬上涉及到所有的模塊。

我們必須承認 J2EE 是龐大的體系。如果一個開發小組只是開始使用 J2EE,這將很難一下子就能掌握它。在 J2EE 中有太多的概念和 API 需要掌握。在這種情況下,成功掌握 J2EE 的關鍵是從簡單的步驟開始做起。

這種方法可以通過在您的應用程序中創建小而簡單的模塊來得到最好的實現。如果一個開發小組通過創建一個簡單的域模型以及后端的持久性機制(也許使用的是 JDBC),并且對其進行了完整的測試,這會增強他們的自信心,于是他們會使用該域模型去掌握使用 servlet 和 JSP 的前端開發。如果一個開發組發現有必要使用 EJB,他們也會類似地開始在容器管理的持久性 EJB 組件之上使用簡單的會話 Facades,或者使用基于 JDBC 的數據訪問對象(JDBC-based Data Access Objects,DAO),而不是跳過這些去使用更加復雜的構造(例如消息驅動bean和JMS)。

這種方法并不是什么新方法,但是很少有開發組以這種方式來培養他們的技能。相反地,多數開發組由于嘗試馬上就構建所有的模塊,同時涉及 MVC 中的視圖層、模型層和控制器層,這樣做的結果是他們往往會陷入進度的壓力之中。他們應該考慮一些敏捷(Agile)開發方法,例如極限編程(XP),這種開發方法采用一種增量學習及開發方法。在 XP 中有一種稱為 ModelFirst 的過程,這個過程涉及到首先構建域模型作為一種機制來組織和實現用戶場景。基本說來,您要構建域模型作為您要實現的用戶場景的首要部分,然后在域模型之上構建一個用戶界面(UI)作為用戶場景實現的結果。這種方法非常適合讓一個開發組一次只學到一種技術,而不是讓他們同時面對很多種情況(或者讓他們讀很多書),這會令他們崩潰的。

還有,對每個應用程序層重復的開發可能會包含一些適當的模式及最佳實踐。如果您從應用程序的底層開始應用一些模式如數據訪問對象和會話 Facades,您就不應該在您的JSP和其他視圖對象中使用域邏輯。

最后,當您開發一些簡單的模塊時,在開始的初期就可以對您的應用程序進行性能測試。如果直到應用程序開發的后期才進行性能測試的話,這往往會出現災難性的后果。


6. 當使用 EJB 組件時,始終使用會話 Facades。

決不要將實體 bean 直接暴露給任何用戶類型。對實體 bean 只可以使用本地 EJB 接口(Local EJB interfaces)。

當使用 EJB 組件時,使用一個會話 Facades 是一個確認無疑的最佳實踐。實際上,這個通用的實踐被廣泛地應用到任何分布式的技術中,包括 CORBA、EJB 和 DCOM。從根本上講,您的應用程序的分布“交叉區域”越是底層化,對小塊的數據由于多次重復的網絡中繼造成的時間消耗就越少。要達到這個目的的方法就是:創建大粒度的 Facades 對象,這個對象包含邏輯子系統,因而可以通過一個方法調用就可以完成一些有用的業務功能。這種方法不但能夠降低網絡開銷,而且在 EJB 內部通過為整個業務功能創建一個事務環境也可以大大地減少對數據庫的訪問次數。

EJB 本地接口(從 EJB 2.0 規范開始使用)為共存的 EJB 提供了性能優化方法。本地接口必須被您的應用程序顯式地進行訪問,這需要代碼的改變和防止以后配置 EJB 時需要應用程序的改變。由于會話 Facades 和它包含的整個 EJB 對于彼此來說都應該是本地的,我們建議對會話 Facades 后面的實體 bean 使用本地接口。然而,會話 Facades 本身的實現(典型例子如無狀態會話 bean)應該設計為遠程接口。

為了性能的優化,可以將一個本地接口添加到會話 Facades。這樣做利用了這樣一個事實:在大多數情況下(至少在 Web 應用程序中),您的 EJB 客戶端和 EJB 會共同存在于同一個 Java 虛擬機(JVM)中。另外一種情況,如果會話 Facades 在本地被調用,可以使用 J2EE 應用服務器配置優化(configuration optimizations),例如 WebSphere 中的“No Local Copies”。然而,您必須注意到這些可供選擇的方案會將交互方法從按值傳遞(pass-by-value)改變為按引用傳遞(pass-by-reference)。這可能會在您的代碼中產生很微妙的錯誤。當您要利用這些方案時,您應該在一開始就考慮其可行性。

如果在您的會話 Facades 中使用遠程接口(而不是本地接口),您也可以將同樣的會話 Facades 在 J2EE 1.4 中以兼容的方式作為 Web 服務來配置。這是因為 JSR 109(J2EE 1.4 中的 Web 服務部署部分)要求使用無狀態會話 bean 的遠程接口作為 EJB Web 服務和 EJB 實現的接口。這樣做是值得的,因為這樣做可以為您的業務邏輯增加客戶端類型的數量。


7. 使用無狀態會話 bean,而不是有狀態會話 bean。

這樣做可以使您的系統經得起錯誤的終止。使用 HttpSession 存儲和用戶相關的狀態。

以我們的觀點看來,有狀態會話 bean 的概念已經過時了。如果您仔細對其考慮一下,一個有狀態會話 bean 實際上與一個 CORBA 對象在體系結構上是完全相同的,無非就是一個對象實例,綁定到一個服務器,并且依賴于服務器來管理其生命周期。如果服務器關閉了,這種對象也就不存在,那么這個 bean 的客戶端的信息也就不存在。

J2EE 應用服務器為有狀態會話 bean 提供的故障轉移(failover)能夠解決一些問題,但是有狀態的解決方案沒有無狀態的解決方案易于擴展。例如,在 WebSphere Application Server 中,對無狀態會話 bean 的請求,是通過對部署無狀態會話的成員集群進行平衡加載來實現。相反地,J2EE 應用服務器不能對有狀態 bean 的請求進行平衡加載。這意味著您的集群中的服務器的加載過程會是不均衡的。此外,使用有狀態會話 bean 將會再添加一些狀態到您的應用服務器上,這也是不好的做法。這樣就增加了系統的復雜性,并且在出現故障的情況下使問題變得復雜化。創建健壯的分布式系統的一個關鍵原則是盡量使用無狀態行為。

因此,我們建議對大多數應用程序使用無狀態會話 bean 方法。任何在處理時需要使用的與用戶相關的狀態應該以參數的形式傳送到 EJB 的方法中(并且通過使用一種機制如 HttpSession 來存儲它)或者從持久性的后端存儲(例如通過使用實體 bean)作為 EJB 事務的一部分來進行檢索。在合適的情況下,這個信息可以緩存到內存中,但是要注意在分布式的環境中保存這種緩存所潛在的挑戰性。緩存非常適合于只讀數據。

總之,您要確保從一開始就要考慮到可伸展性。檢查設計中的所有設想,并且考慮到當您的應用程序要在多個服務器上運行時,是否也可以正常運行。這個規則不但適合上述情況的應用程序代碼,也適用于如 MBean 和其他管理界面的情況下。


8. 使用容器管理的事務。

學習一下 J2EE 中的兩階段提交事務,并且使用這種方式,而不是開放您自己的事務管理。容器在事務優化方面幾乎總是比較好的。

使用容器管理的事務(CMT)提供了兩個關鍵的優勢(如果沒有容器支持這幾乎是不可能的):可組合的工作單元和健壯的事務行為。

如果您的應用程序代碼顯式地使用了開始和結束事務(也許使用 javax.jts.UserTransaction 或者甚至是本地資源事務),而將來的要求需要組合模塊(也許會是代碼重構的一部分),這種情況下往往需要改變事務代碼。例如,如果模塊 A 開始了一個數據庫事務,更新數據庫,隨后提交事務,并且有模塊 B 做出同樣的處理,請考慮一下當您在模塊 C 中嘗試使用上述兩個模塊,會出現什么情況呢?現在,模塊 C 正在執行一個邏輯動作,而這個動作實際上將調用兩個獨立的事務。如果模塊 B 在執行中失敗了,而模塊 A 的事務仍然能被提交。這是我們所不希望出現的行為。如果,相反地,模塊 A 和模塊 B 都使用 CMT 的話,模塊 C 也可以開始一個 CMT(通常通過配置描述符),并且在模塊 A 和模塊 B 中的事務將是同一個事務的隱含部分,這樣就不再需要復雜的重寫代碼的工作了。

如果您的應用程序在同一個操作中需要訪問多種資源,您就要使用兩階段提交事務。例如,如果從 JMS 隊列中刪除一個消息,并且隨后更新基于這條消息的紀錄,這時,要保證這兩個操作都會執行或都不會執行就變得尤為重要。如果一條消息已經從隊列中被刪除,而系統沒有更新與此消息相關的數據庫中的紀錄,那么這種系統是不穩定的。一些嚴重的客戶及商業糾紛源自不一致的狀態。

我們時常看到一些客戶應用程序試圖實現他們自己的解決方案。也許會通過應用程序的代碼在數據庫更新失敗的時候 “撤銷”對隊列的操作。我們不提倡這樣做。這種實現要比您最初的想象要復雜得多,并且還有許多其他的情況(想象一下如果應用程序在執行此操作的過程中突然崩潰的情況)。作為替代的方式,應該使用兩階段提交事務。如果您使用 CMT,并且在一個單一的 CMT 中訪問兩階段提交的資源(例如 JMS 和大多數數據庫),WebSphere 將會處理所有的復雜工作。它將確保整個事務被執行或者都不被執行,包括系統崩潰、數據庫崩潰或其他的情況。其實現在事務日志中保存著事務狀態。當應用程序訪問多種資源的時候,我們怎么強調使用 CMT 事務的必要性都不為過。


9. 將 JSP 作為表示層的首選。

只有在需要多種表示輸出類型,并且輸出類型被一個單一的控制器及后端支持時才使用 XML/XSLT。

我們常聽到一些爭論說,為什么您選擇 XML/XSLT 而不是 JSP 作為表示層技術。選擇 XML/XSLT 的人的觀點是,JSP“ 允許您將模型和視圖混合在一起”,而 XML/XSLT 不會有這種問題。遺憾的是,這種觀點并不完全正確,或者至少不像白與黑那樣分的清楚。實際上,XSL 和 XPath 是編程語言。XSL 是圖靈完成的(Turing-complete),盡管它不符合大多數人定義的編程語言,因為它是基于規則的,并且不具備程序員習慣的控制工具。

現在的問題是既然給予了這種靈活性,開發人員就會利用這種靈活性。盡管每個人都認同 JSP 使開發人員容易在視圖中加入“類似模型”的行為,而實際上,在 XSL 中也有可能做出一些同樣的事情。盡管從 XSL 中進行訪問數據庫這樣的事情會非常困難,但是我們曾經見到過一些異常復雜的 XSLT 樣式表執行復雜的轉換,這實際上是模型代碼。

然而,應該選擇 JSP 作為首選的表示技術的最基本的原因是,JSP 是現在支持最廣泛的、也是最被廣泛理解的 J2EE 視圖技術。而隨著自定義標記庫、JSTL 和 JSP2.0 的新特性的引入,創建 JSP 變得更加容易,并且不需要任何 Java 代碼,以及可以將模型和視圖清晰的分離開。在一些開發環境中(如 WebSphere Studio)加入了對 JSP(包括對調試的支持)的強大支持,并且許多開發人員發現使用 JSP 進行開發要比使用 XLS 簡單,一些支持 JSP 的圖形設計工具及其他特征(尤其在 JSF 這樣的框架下)使得開發人員可以以所見即所得的方式進行 JSP 的開發,而對于 XSL 有時不容易做到。

最后一個要謹慎考慮使用 JSP 的原因是速度問題。在 IBM 所作的對比 XSL 和 JSP 相對速度的性能測試顯示:在大多數情況下,JSP 在生成同樣的 HTML 的時候,要比 XSL 快好幾倍,甚至使用編譯過的 XSL 也是如此。盡管多數情況下這不是問題,但在性能要求很高的情況下,這就會成為問題。

然而,這也不能說,您永遠也不要使用 XSL。在一些情況下,XSL 能夠表示一組固定的數據,并且可以基于不同的樣式表來以不同的方式顯示這些數據的能力是顯示視圖的最佳解決方案。然而,這只是一種例外的情況,而不是通用的規則。如果您只是生成 HTML 來表達每一個頁面,那么在大多數情況下,XSL 是一種不必要的技術,并且,它給您的開發人員所帶來的問題遠比它所能解決的問題多。


10. 當使用 HttpSession 時,盡量只將當前事務所需要的狀態保存其中,其他內容不要保存在 HttpSession 中。

啟用會話持久性。

HttpSessions 對于存儲應用程序狀態信息是非常有用的。其 API 易于使用和理解。遺憾的是,開發人員常常遺忘了 HttpSession 的目的——用來保持暫時的用戶狀態。它不是任意的數據緩存。我們已經見到過太多的系統為每個用戶的會話放入了大量的數據(達到兆字節)。那好了,如果同時有 1000 個登錄系統的用戶,每個用戶擁有 1MB 的會話數據,那么就需要 1G 或者更多的內存用于這些會話。要使這些 HTTP 會話數據較小一些,不然的話,您的應用程序的性能將會下降。一個大約比較合適的數據量應該是每個用戶的會話數據在 2K-4K 之間,這不是一個硬性的規則,8K 仍然沒有問題,但是顯然會比 2K 時的速度要慢。一定要注意,不要使 HttpSession 變成數據堆積的場所。

一個常見的問題是使用 HttpSession 緩存一些很容易再創建的信息,如果有必要的話。由于會話是持久性的,進行不必要的序列化以及寫入數據是一種很奢侈的決定。相反地,應該使用內存中的哈希表來緩存數據,并且在會話中保存一個對此數據進行引用的關鍵字。這樣,如果不能成功登錄到另外的應用服務器的話,就可以重新創建數據。

當談及會話持久性時,不要忘記要啟用這項功能。如果您沒有啟用會話持久性,或者服務器因為某種原因停止了(服務器故障或正常的維護),則所有此應用服務的當前用戶的會話將會丟失。這是件令人非常不高興的事情。用戶不得不重新登錄,并且重新做一些他們曾經已經做過的事情。相反地,如果啟用了會話持久性,WebSphere 會自動將用戶(以及他們的會話)移到另外一個應用服務器上去。用戶甚至不知道會有這種事情的發生。我們曾經見到過一些產品系統因為存在于本地代碼中令人難以忍受的 bug(不是 IBM 的代碼!)而突然崩潰的情況,這這種情況下,上述功能仍然可以運行良好。


11. 在 WebSphere 中,使用動態緩存,并使用 WebSphere servlet 緩存機制.

通過使用這些功能,系統性能可以得到很大的提高,而開銷是很小的。并且不影響編程模型。

通過緩存來提高性能的好處是眾所周知的事情。遺憾的是,當前的 J2EE 規范沒有包括一種用于 servlet/JSP 緩存的機制。然而,WebSphere 提供了對頁面以及片斷緩存的支持,這種支持是通過其動態緩存功能來實現的,并且不需要對應用程序作出任何改變。其緩存的策略是聲明性的,而且其配置是通過 XML 配置描述符來實現的。因此,您的應用程序不會受到影響,并保持與 J2EE 規范的兼容性和移植性,同時還從 WebSphere 的 servlet 及 JSP 的緩存機制中得到性能的優化。

從 servet 及 JSP 的動態緩存機制得到的性能的提高是顯而易見的,這取決于應用程序的特性。Cox 和 Martin [Cox] 指出對一個現有的 RDF(資源描述格式)站點摘要 (RSS)servlet,當使用動態緩存時,其性能可以提高 10%。請注意這個實驗只涉及到一個簡單的 servlet,這個性能的增長量可能并不能反映一個復雜的應用程序。

為了更多地提高性能,將 WebSphere servlet/JSP 結果緩存與 WebSphere 插件 ESI Fragment 處理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) 和 Edge Server 緩存功能集成在一起。對于繁重的基于讀取的工作負荷,通過使用這些功能可以得到許多額外的好處。


12. 為了提高程序員的工作效率,將 CMP 實體 bean 作為 O/R 映射的首選解決方案.

通過 WebSphere 框架(readahead、緩存、隔離級別等)優化性能。如果可能,有選擇的應用一些模式來達到提高性能的目的,例如 Fast-Lane 閱讀器 [Marinescu]。

對象/關系(O/R)映射是使用 Java 創建企業級的應用程序的基礎。幾乎每個 J2EE 應用程序都需要一些類型的 O/R 映射。J2EE 廠商提供一種 O/R 映射機制,這種機制在不同的廠商間是可移植的,高效的,并且能夠被一些標準及工具很好地支持。這就是 EJB 規范中的 CMP(容器管理的持久性)部分。

早期的 CMP 實現以表現不佳及不支持許多 SQL 結構而著稱。然而,隨著 EJB 2.0 及 2.1 規范的出現,以及被一些廠商所采納,并且隨著像 IBM WebSphere Studio Application Developer 的出現,這些問題已經不再是問題了。

CMP EJB 組件現在已經被廣泛地應用于許多高性能的應用程序中。WebSphere 包括一些優化功能以提高 EJB 組件的性能,優化功能包括:對生命周期的緩存和 read-ahead 能力。這兩者優化功能都是配置時的選項,并且不需要對應用程序進行修改或者影響可移植性。

處于緩存狀態的生命周期緩存 CMP 狀態數據并提供基于時間的無效性。從處于緩存狀態的生命周期得到的性能提高可以達到選項 A 的緩存性能,并且仍然可以為您的應用程序提供可伸展性。Read-ahead 能力和容器管理的關系結合使用。這個特性通過在相同的查詢中隨意地檢索相關的數據作為父數據而減少與數據庫的交互。如果相關的數據要通過使用并發的查詢來訪問的話,這種方法可以得到性能的改進。[Gunther]提供了詳細的描述以及通過這些特性得到的性能提高的細節。

此外,為了完全優化您的 EJB 組件,當指定隔離級別時要特別注意。盡可能使用最低的隔離級別,并且仍然保持您的數據的完整性。較低的隔離級別可以提供最佳的性能,并且可以降低出現數據庫死鎖的危險。

這是目前最有爭議的最佳實踐。已經有大量的文章贊揚 CMP EJB,同樣的貶斥聲也不絕于耳。然而,這里最基本的問題是數據庫開發是困難的。當您開始使用任何持久性解決方案之前,您需要掌握查詢以及數據庫鎖定如何工作這些基礎知識。如果您選擇使用 CMP EJB,您要確保您已經通過一些書籍(例如 [Brown] 和 [Barcia])知道如何使用它們。在鎖定及爭用方面有一些微妙的交互難以理解,但是,在您耗費一定的時間及努力后會將其掌握的。


結束語

在這個簡短的摘要中,我們已經向您介紹了 J2EE 中的核心模式和最佳實踐,這使得 J2EE 開發成為一種可管理的過程。盡管我們并沒有給出所有在實踐中使用這些模式的必要細節,但是我們希望能夠給您足夠的指點和指導,以幫助您決定下一步要做什么。



夢幻流星 2008-01-03 14:25 發表評論
]]>
中文編碼http://www.aygfsteel.com/isoft/archive/2008/01/03/172440.html夢幻流星夢幻流星Thu, 03 Jan 2008 05:14:00 GMThttp://www.aygfsteel.com/isoft/archive/2008/01/03/172440.htmlhttp://www.aygfsteel.com/isoft/comments/172440.htmlhttp://www.aygfsteel.com/isoft/archive/2008/01/03/172440.html#Feedback0http://www.aygfsteel.com/isoft/comments/commentRss/172440.htmlhttp://www.aygfsteel.com/isoft/services/trackbacks/172440.html
GB2312:簡體中文編碼,一個漢字占用2字節,在大陸是主要編碼方式。當文章/網頁中包含繁體中文、日文、韓文等等時,這些內容可能無法被正確編碼。

BIG5:繁體中文編碼。主要在臺灣地區采用。

GBK:支持簡體及繁體中文,但對他國非拉丁字母語言還是有問題。

UTF-8:Unicode編碼的一種。Unicode用一些基本的保留字符制定了三套編碼方式,它們分別UTF-8,UTF-16和UTF-32。在UTF-8中,字符是以8位序列來編碼的,用一個或幾個字節來表示一個字符。這種方式的最大好處,是UTF-8保留了ASCII字符的編碼做為它的一部分。UTF-8俗稱“萬國碼”,可以同屏顯示多語種,一個漢字占用3字節。為了做到國際化,網頁應盡可能采用UTF-8編碼。當然,處理中文時http頭也要改成UTF-8編碼的-----加上<meta http-equiv="Content-Type" content="text/html; charset=utf-8">。

夢幻流星 2008-01-03 13:14 發表評論
]]>
主站蜘蛛池模板: 望江县| 平遥县| 达拉特旗| 从江县| 哈尔滨市| 周至县| 伊金霍洛旗| 镇巴县| 罗城| 霍城县| 门头沟区| 定州市| 健康| 兴文县| 新邵县| 林口县| 卢龙县| 望江县| 社会| 通海县| 泗洪县| 义乌市| 昔阳县| 特克斯县| 南召县| 报价| 辉县市| 观塘区| 南安市| 马尔康县| 南通市| 会泽县| 高碑店市| 南康市| 商丘市| 鲁甸县| 瓮安县| 威远县| 银川市| 吐鲁番市| 中超|