[转载]三、二、一 …… Geronimo!,第 3 部分: 状态问题
三、二、一 …… Geronimo!,第 3 部分: 狀態問題
盡管計算機和 Web 使日常的任務變得更加便利,但它們也帶來了一些新的挑戰。如今的 Internet,其運行再也不僅僅限于對 HTML 編碼的 Web 頁面的請求做出響應。當今的 Web 站點必須能夠維護大量的用戶信息,并且能夠管理許多復雜的任務。幸運的是,現在已經有一些前沿的工具能夠用來簡化這類狀態問題。其中一種具有行業水準的解 決方案脫穎而出,它就是會話狀態。本文演示了 Apache Geronimo 如何能夠維護成千上萬個同時連接的狀態,這樣一來,IT 經理們就可以松口氣了。
我們創建計算機和通信技術是用來簡化生活的,不是嗎?盡管表面看起來并非如此 —— 這些技術的確帶來了其自身的一些復雜性 —— 但它們的確可以讓我們實現一些原來所不能實現的事情,從這個意義上講,它們確實讓人們的生活變得簡單和方便了。
例如,現在您可以從早餐桌走到起居室的電腦旁來查看一下當前的氣象雷達或道路狀況,或者訂購一盆新的室內植物,當然也可以結算支票簿、支付賬單等等,而這在幾十年前(花如此少的力氣)簡直是不可想象的。這確實是一種進步,但其產生也少不了路途中的一些磕磕絆絆。
Web 過去的好時光
在 過去,從某種意義上講,萬維網(World Wide Web)就是一個電子的超級高速公路,在這里,那些敢于開拓的公司用特異的布告牌,以當時能夠實現的最佳視覺方式展示其產品。人們被其吸引進而會閱讀這些 布告牌,然后打電話給這些公司了解更多關于產品的信息,再通過傳統的方式來完成交易:電話交易或親自前往(購買)。
沒過多久,計算機程序員們就為發生在布告牌(其實是 Web 站點本身)上的買賣雙方的交易創建了一種更為交互的方式。從而,聯系我們 窗體、粗糙的購物車及其他簡單的 Web 應用程序就誕生了。
從前,Web 站點只需要對超文本標記語言(HTML)編碼的 Web 頁面的請求做出響應。現在,Web 站點必須記住訪客的信息,這些信息是同該訪客進行交易所必需的。
突然間,人們不得不在登錄 Web 站點的時候提供這樣的信息,即是誰、想買什么、想以什么方式購買,Web 站點必須維護這些信息。Web 服務器再也不能這樣簡單地答復其調用者了,即向他/她發送一個頁面后就完事大吉。按照計算機界的說法,這些任務即狀態問題 ,這個問題將 Web 在其幼年時期曾經享用的那種簡單的請求-響應的模式復雜化了。
如 今,我們都處在這樣一個時代,每個想要讓其商業及其業務模式在 21 世紀能夠生存下來的公司都有一個 Web 站點,狀態問題(由此變得)至關重要。如果用戶 12317 不能在線購買 1437 公司的 8945 號產品,該用戶就能夠在從起居室的電腦旁走到廚房找些吃的東西之前,利用搜索引擎找到能夠將該商品賣給他/她的 4783 公司,換言之,一切都太方便了。
但為購買產品的用戶簡化了購買過程即意味著要有其他人為這部分無形的價格買賬,世上沒有免費的午餐,這是一個不言而喻的道理。Web 服務器和 Web 應用程序是包含了許多獨立組件的復雜系統,這些組件本身又有其復雜性:數據庫引擎、安全機制、信用卡驗證引擎等等。
|
減輕職業 IT 人的負擔
免 費(軟件)市場像往常一樣出來救援了。如今的 Internet 工程師們能夠從大量工具和供應商產品中挑選,這些工具和產品讓商業的車輪仍舊能夠向前滾動并一路高歌。要獲取針對狀態問題的行業水準的解決方案,請考慮由 Apache Geronimo 為代表的 Java? 2 Platform, Enterprise Edition(J2EE?)引擎。
在典型的大型業務程序中,每個小時中,都會調用單獨的應用程序來對成千上萬的匿名瀏覽器發出的無休止的請求系列做出響應。當然,幾百個左右的瀏覽器自身會帶有一些服務器軟件所熟悉的信息,這些瀏覽器就是那些帶 cookie 的客戶機瀏覽器。
這 些 cookie 最初就被植入到匿名的用戶 Web 瀏覽器上,從而可以確認用戶這次是否是再次光顧 —— 辨認出老客戶對公司來說是件好事!客戶機狀態集就是在這里存儲的。Cookie 也許僅僅由一個簡單的鍵值組成,該值用于解鎖存儲于公司數據庫中有關此用戶的大量信息。
當一個已知客戶再次光顧且(服務器)認出 了該用戶的瀏覽器所提供的 cookie 時,狀態問題就解決了一半。很快,服務器軟件能夠用各種有用信息定制頁面,如個人化的歡迎頁面或首選的偏好頁面。還會顯示一份與用戶過去購買的產品相似的 產品清單和一些誘人的折扣,這些折扣基本上向用戶傳達了這樣的信息,即他或她是一名寶貴的客戶,因而公司非常歡迎該用戶的再次光顧,希望其購買更多的東 西。
|
客戶機狀態
用 Internet 工程師們的行話講,這種發生在一個經過認證的客戶機瀏覽器和服務器間的 Web 站點的對話叫做會話 。會話的狀態 (已保存的關于客戶及其購買習慣的信息)保存在服務器的超文本傳輸協議(HTTP)的范圍之外,因為根據定義,它是一個無狀態的協議。.
|
Geronimo 中的 Java servlet 技術提供了自動創建并管理會話的應用編程接口(API)。這項功能的核心駐留在 HttpSession 對象中,可以通過調用請求對象的 getSession() 方法來訪問會話。此方法返回與此請求相關聯的當前會話;如果沒有這樣的會話,該方法會自動創建一個并返回新創建的會話句柄。欲了解更多信息,請參見側欄中的 Geronimo 會話樣例 。
如果將 cookie 用作會話跟蹤機制(還有其他方法),servlet 代碼中的 getSession() 方法能夠修改響應標頭信息 —— 特別是通過自動創建一個新會話(如果該請求尚不具備與之相關聯的會話時)。諸如這樣的功能是令人叫絕的。會話以及它們可以從持久存儲中創建并回調對于那些已經十分繁忙的程序員們來說真是一個 “救命” 的機制。
為簡化并自動化傳遞代表這個 用戶狀態的其他信息,可以用名稱=值的方式將屬性值和會話關聯起來。如 清單 1 中的代碼片段所示。
清單 1. ShoppingCartServlet
| public class ShoppingCartServlet extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get session and current shopping cart information. HttpSession theSession = request.getSession(); TheShoppingCart theCart = (TheShoppingCart) session.getAttribute(thecart); . . . // Calculate the total price of all items in the cart. double totalPrice = theCart.getTotal(); |
大量的處理都在其幕后進行,這些處理居于 Geronimo 的核心來維護之前所描述過的狀態問題,并且 Java servlet 機制會掩藏這些細節。信息存儲于請求之間,所以總能知道一個給定用戶和公司的(交易)歷史記錄。
實現維護客戶機瀏覽器狀態的 HttpSession 方法的應用程序也具有和其使用相關聯的重要的附加功能。在這些附加的功能中,其中一種功能是能夠用來自動通知會話關系中其他對象的。例如,如果一些對象實現了 javax.http.HttpSessionBindingListener 接口,那么它們就可以被告知它們已經被添加到一個會話中或已經從一個會話中刪除。
如果與對象相關聯的會話是被動的或主動的,如在虛擬機(VM)間或持久性存儲間移動,當該對象實現了 javax.http.HttpSessionActivationListener 接口時,就能夠向該對象通知這項改變。
像這樣的事件通知讓對象能夠在特定的時間完成與正在發生事件密切相關的事情,如將會話已經發生這一事實記入日志,這將導致會記錄下更多的用戶購物習慣。可以用這種方式觸發各種各樣的高級數據挖掘規則。
|
服務器狀態
服 務器上進行的會話管理包括許多任務,這些任務也許在直觀上并不明顯。但每個會話都消耗服務器資源(特別是內存),這些資源必須在會話超時時收回。會話的超 時值依賴于許多因素,對這些因素的詳細介紹超出了本文討論的范圍,可以用應用程序的部署工具來設定該值。或者,會話對象本身可以通過調用 getMaxInactiveInterval() 或 setMaxInactiveInterval() 方法來獲取或設定該超時值。
每個會話都有一個與其相關聯的生存時間計數器,一個比較好的做法是定時地使用服務方法來訪問該會話,因為這樣做會重置計數器且會阻止會話的超時(實例化及終止會話會消耗大量的 CPU 和內存資源,因而最好是在合理的時間內保持會話的活動)。
這就是為什么要向用戶顯示 Sign out 或 Log off 這類的按鈕并鼓勵用戶去使用這些按鈕的原因之一。當用戶單擊該按鈕時,實質上告知服務器該會話已經結束,隨后會調用該會話的 invalidate() 方法來清理服務器上該會話的數據并收回前面提到的資源。清單 2 中的代碼說明了這一過程。
清單 2. FinishServlet
| public class FinishServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get session and shopping cart information and end the session. HttpSession theSession = request.getSession(); theSession.invalidate(); |
|
跟蹤難以捉摸的客戶
如 前所述,有幾種可用的方法將會話信息和特定的用戶關聯起來,所有這些方法都要求在客戶機和服務器計算機間傳遞一定種類的標識符。已經提到的一種方法是 cookie 方法。另一種方法是將該標識符包含到每一個后來發送回客戶機瀏覽器的 URL 中。這個標識符(通常是數據庫鍵)能夠作為該 URL 參數之一而生成并發送到客戶機。很肯定地說,如果您看到和下列相似的 URL 時,就說明您正在被跟蹤:http://www.somedomain.com/applications/thecart?jsessionid= 868D6879824E0F3FB499D8146A9EE7F
這個叫做 jsessionid 的十六進制數字是到 Geronimo 會話句柄的主鍵,并為系統提供了關于您的信息(您在過去某時提供的)。這是一個會話編號(準備好再現關于您的數據),它存儲在之前對 Web 站點訪問的持久性存儲中。使用該方法維護狀態有諸多優勢,最顯著的是它并不依賴用戶瀏覽器 cookie 機制的打開(正如時下許多人所做的)。
Web 應用程序必須重寫每一個在 Web 頁面中發送給用戶的 URL,否則將丟失該會話信息。如果用 J2EE 的方式(因而也是 Geronimo 方式)來實現,就要對所有由 servlet 返回的 URL 調用響應對象的 encodeURL() 方法。這樣,只有當用戶瀏覽器關閉了 cookie 處理,生成的 URL 中才會包含會話 ID。否則,瀏覽器返回未改變的 URL,例如:
out.println(" response.encodeURL(request.getContextPath() +"/thecart") + "">Continue Shopping?");
如果用戶關閉了瀏覽器中的 cookie,將看到與此類似的(顯示):http://www.somedomain.com/applications/thecart?jsessionid=868D6879824E0F3FB499D8146A9EE7F 。
但如果 cookie 機制仍打開著,將看到與此類似的(顯示):http://www.somedomain.com/applications/thecart 。
|
結束語
通 過使用頂級的工具,如 Geronimo 及其所實現的 J2EE 技術,現代 Web 應用程序所必須維護的許多狀態問題都可以得到極大的簡化。如果您是一個珍惜自己睡眠時間的公司經理,那么您盡可以高枕無憂,因為 Geronimo 架構可以為您的客戶提供愉快的體驗以使其在下次光顧時仍能保持愉悅;該架構還可以讓您的程序員們也非常滿意,因為它可以為程序員們提供一個可靠的環境以使 維護用戶狀態變得十分簡單。
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/374079/viewspace-130302/,如需轉載,請注明出處,否則將追究法律責任。
轉載于:http://blog.itpub.net/374079/viewspace-130302/
總結
以上是生活随笔為你收集整理的[转载]三、二、一 …… Geronimo!,第 3 部分: 状态问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WASCE (基于geronimo )
- 下一篇: 如何用java获取网页源代码