第三個範例:ZK 與 Session
The following examples had been tested on Mozilla's Firefox and Microsoft's IE. The document is provided as is. You are welcomed to use it for non-commercial purpose.Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼
看其他教材
ZK 跟所有 Web-based 的資訊系統一樣,網頁跟網頁之間都是互為獨立的 (稱之為 stateless),可是在實務上,往往網頁與網頁之間是有順序關係的; 例如如果使用者沒有登入,那麼使用者就不能修改使用者的註冊資料。 為了能夠達到這個目的,一般 Web-based 的資訊系統都利用 Session 的作法, 讓網頁與網頁之間可以藉由 Session 物件的一些共享資料來達成。在 ZK 中, 它也提供了類似的 package,這個 package 的名稱為 org.zkoss.zk.ui.Session; 除了這個範例之外,讀者可以參考該 package 的其他類別以及用法。 在這個範例中,我們假設設計一個系統,該系統有多個網頁,而要使用該系統, 使用者必須先執行 login.zul 網頁;一旦登入成功之後,使用者就能使用 其他網頁;為了簡化起見,我們只設計了一個 zul 網頁 todo1.zul(該網頁 是 todo.zul 的簡化版),其他網頁可以比照辦理。如果使用者未登入便想 直接存取 todo1.zul,則使用者會被導向 login.zul。
首先,讓我們設計 login.zul 的畫面,其畫面如下:
01 <?xml version="1.0" encoding="Big5"?> 02 <?page title="待辦事項系統"?> 03 <window title="登入畫面" border="normal" width="220px" mode="modal" 04 xmlns:h="http://www.w3.org/1999/xhtml"> 05 <h:table> 06 <h:tr> 07 <h:td>帳號:</h:td><h:td><textbox id="user"/></h:td> 08 </h:tr><h:tr> 09 <h:td>密碼:</h:td><h:td><textbox type="password" id="pwd"/></h:td> 10 </h:tr><h:tr> 11 <h:td colspan="2" align="center"><button label="登入"/></h:td> 12 </h:tr> 13 </h:table> 14 </window>
在使用者輸入帳號和密碼之後,使用者會點一下"登入"按鈕;一旦"登入"按鈕 被點選,login() 方法會被執行。該事件的註冊方式如下:
<button label="登入" onClick="login()"/>
01 import org.zkoss.zk.ui.*; 02 03 void login() { 04 // 也可以連資料庫驗證 05 if(user.value.equals("123") && pwd.value.equals("123")) { 06 Session s = Sessions.getCurrent(); 07 s.setAttribute("user", user.value); 08 s.setAttribute("pwd", pwd.value); 09 Executions.sendRedirect("todo1.zul"); 10 } else { 11 Executions.sendRedirect("login.zul"); 12 } 13 }
todo1.zul 是第二個範例的簡易版,其畫面的定義部分如下:
<?xml version="1.0" encoding="Big5"?> <window title="待辦事項清單" width="640px" border="normal" closable="true" onClose="self.visible=false;logout();"> <listbox id="box" multiple="true" rows="4"> <listhead> <listheader label="待辦事項" /> <listheader label="重要性" width="50px" /> <listheader label="日期" width="90px" /> </listhead> </listbox> </window>
另外,除了 login.zul,所有同一個系統中的其他網頁應該在載入的時候,就應該檢查 Session 中的共用資料(在本範例中即屬性名稱為 user 以及 pwd 是否存在, 必要的話,還可以檢查屬性的值是否存在)。為了做這兩件事,程式碼如下:
01 import org.zkoss.zk.ui.*; 02 03 Session s = Sessions.getCurrent(); 04 if(s.getAttribute("user") == null) 05 Executions.sendRedirect("login.zul"); 06 07 void logout() { 08 s.invalidate(); 09 Executions.sendRedirect("login.zul"); 10 }
我們鼓勵讀者試著從各種方式來使用 Session。例如:開啟一個新的網頁之後, 馬上試著連 todo1.zul;或者 logout 之外,直接更改 URL 試圖連接 todo1.zul。 有了良好的 Session 控制,這些方式都不應該可以連上 todo1.zul;除了 正確的登入。
在測試的過程中,你或許會發現雖然在無法順利使用 todo1.zul 的情形下, 使用者還是有一個短暫的時間可以看到 todo1.zul 的畫面,如果該畫面有 一些機密內容,那麼 todo1.zul 的設計還是不妥。為了解決這個問題,我們 可以在一開始讓 <window> 是看不到的,只有使用者正確的登入後 才讓 <window> 能夠顯示出來。由於程式碼還蠻簡單的,我們就不再說明, 而把整個程式碼的內容列示出來:
<?xml version="1.0" encoding="Big5"?> <window id="win" title="待辦事項清單" width="640px" border="normal" closable="true" visible="false" onClose="self.visible=false;logout();"> <zscript> import org.zkoss.zk.ui.*; Session s = Sessions.getCurrent(); if(s.getAttribute("user") == null) Executions.sendRedirect("login.zul"); else win.setVisible(true); void logout() { s.invalidate(); Executions.sendRedirect("login.zul"); } </zscript> <listbox id="box" multiple="true" rows="4"> <listhead> <listheader label="待辦事項" /> <listheader label="重要性" width="50px" /> <listheader label="日期" width="90px" /> </listhead> </listbox> </window>
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
沒有留言:
張貼留言