動作事件


JSF支援事件處理模型,雖然由於HTTP本身無狀態(stateless)的特性,使得這個模型多少有些地方仍不太相同,但JSF所提供的事件處理模型已足以讓一些傳統GUI程式的設計人員,可以用類似的模型來開發程式。

簡單的導航 中,我們根據動作方法(action method)的結果來決定要導向的網頁,一個按鈕繫結至一個方法,這樣的作法實際上即使JSF所提供的簡化的事件處理程序,在按鈕上使用action繫 結至一個動作方法(action method),實際上JSF會為其自動產生一個「預設的ActionListener」來處理事件,並根據其傳回值來決定導向的頁面。

如果您需要使用同一個方法來應付多種事件來源,並想要取得事件來源的相關訊息,您可以讓處理事件的方法接收一個 javax.faces.event.ActionEvent事件參數,例如:
  • UserBean.java
package onlyfun.caterpillar;

import javax.faces.event.ActionEvent;

public class UserBean {
private String name;
private String password;
private String errMessage;
private String outcome;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setPassword(String password) {
this.password = password;
}

public String getPassword() {
return password;
}

public void setErrMessage(String errMessage) {
this.errMessage = errMessage;
}

public String getErrMessage() {
return errMessage;
}

public void verify(ActionEvent e) {
if(!name.equals("justin") ||
!password.equals("123456")) {
errMessage = "名稱或密碼錯誤" + e.getSource();
outcome = "failure";
}
else {
outcome = "success";
}
}

public String outcome() {
return outcome;
}
}

在上例中,我們讓verify方法接收一個ActionEvent物件,當使用者按下按鈕,會自動產生ActionEvent物件代表事件來源,我們故意在錯誤訊息之後如上事件來源的字串描述,這樣就可以在顯示錯誤訊息時一併顯示事件來源描述。

為了提供ActionEvent的存取能力,您的index.jsp可以改寫如下:
  • index.jsp
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@page contentType="text/html;charset=Big5"%>
<html>
<head>
<title>第一個JSF程式</title>
</head>
<body>
<f:view>
<h:form>
<h3>請輸入您的名稱</h3>
<h:outputText value="#{user.errMessage}"/><p>
名稱: <h:inputText value="#{user.name}"/><p>
密碼: <h:inputSecret value="#{user.password}"/><p>
<h:commandButton value="送出"
actionListener="#{user.verify}"
action="#{user.outcome}"/>
</h:form>
</f:view>
</body>
</html>

主要改變的是按鈕上使用了actionListener屬性,這種方法可以使用一個ActionListener,JSF會先檢查是否有指定的 actionListener,然後再檢查是否指定了動作方法並產生預設的ActionListener,並根據其傳回值導航頁面。

如果您要註冊多個ActionListener,例如當使用者按下按鈕時,順便在記錄檔中增加一些記錄訊息,您可以實作 javax.faces.event.ActionListener,例如:
 package onlyfun.caterpillar;

 import javax.faces.event.ActionListener;
 ....

 public class LogHandler implements ActionListener {
     public void processAction(ActionEvent e) {
         // 處理Log
     }
 }
 

 
 package onlyfun.caterpillar;

 import javax.faces.event.ActionListener;
 ....

 public class VerifyHandler implements ActionListener {
     public void processAction(ActionEvent e) {
         // 處理驗證
     }
 }
 

這麼一來,您就可以使用<f:actionListener>標籤向元件註冊事件,例如:
 <h:commandButton value="送出" action="#{user.outcome}">
    <f:actionListener type="onlyfun.caterpillar.LogHandler"/>
    <f:actionListener type="onlyfun.caterpillar.VerifyHandler"/>
 </h:commandButton>
 

<f:actionListener>會自動產生type所指定的物件,並呼叫元件的addActionListener()方法註冊 Listener。