第三個範例: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
沒有留言:
張貼留言