1.JSF動作事件
前面的例子,我們直接將按鈕的action綁定到一個Bean的方法上。實際上當按鈕被觸發(fā)時,JSF會自動產生一個Listener來處理事件。
如果您需要使用同一個方法來應付多種事件來源,并想要取得事件來源的相關訊息,您可以讓處理事件的方法接收一個javax.faces.event.ActionEvent事件參數。
如下jsp:
<%@ taglib
uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib
uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ page
language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title>Insert title
here</title>
</head>
<body>
<f:view>
<f:form>
<h3>JSF動作事件--按鈕觸發(fā)的Listener事件,會在后臺打出log。</h3>
<h:commandButton value="#{msgs.commandText}">
<f:actionListener
type="test.LogHandler"/>
</h:commandButton>
</f:form>
</f:view>
</body>
</html>
生成一個自定義的Listener:
package
test;
import
javax.faces.event.ActionEvent;
import
javax.faces.event.ActionListener;
public
class LogHandler implements ActionListener{
public void processAction(ActionEvent e)
{
System.out.println("++++++++LogHandler+++++++++");
}
}
當按鈕觸發(fā)時,便會激活LogHandler這個Listener。你也可以同時指定多個Listener。
http://localhost:8080/jsfTest/pages/jsfMyActionEvent.faces
就可以看到運行結果了。
具體程序參看示例程序。
2.JSF變量/值變事件
如果使用者改變了JSF輸入元件的值后送出表單,就會發(fā)生值變事件(Value
Change Event),這會丟出一個javax.faces.event.ValueChangeEvent物件。
如果您想要處理這個事件,有兩種方式,一是直接 設定JSF輸入元件的valueChangeListener屬性:
jsfMyValueEvent.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=utf-8"%>
<f:view
locale="#{valueEventBean.locale}">
<f:loadBundle
basename="messages" var="msgs"/>
<html>
<head>
<title><h:outputText
value="#{msgs.titleText}" /></title>
</head>
<body>
<h:form>
<h3><h:outputText
value="#{msgs.hintText}"/></h3>
<h:selectOneMenu
value="#{valueEventBean.locale}"
onchange="this.form.submit();"
valueChangeListener="#{valueEventBean.changeLocale}">
<f:selectItem itemValue="zh_TW"
itemLabel="Chinese"/>
<f:selectItem itemValue="en"
itemLabel="English"/>
</h:selectOneMenu>
</h:form>
</body>
</html>
</f:view>
onchange屬性中使用了JavaScript,其作用是在選項項目發(fā)生改變之后,立即送出表單,而不用按下提交按鈕。
valueChangeListener屬性所綁定的user.changeLocale方法必須接受ValueChangeEvent物件。
JsfMyValueEvent.java
package test;
import javax.faces.event.ValueChangeEvent;
public class JsfMyValueEvent {
private String locale = "en";
public String
changeLocale(ValueChangeEvent e) {
if(locale.equals("en"))
locale = "zh_TW";
else
locale = "en";
return locale;
}
public String getLocale() {
if (locale == null) {
locale = "en";
}
return locale;
}
}
別忘記在faces-config.xml中注冊Bean。
http://localhost:8080/jsfTest/pages/jsfMyValueEvent.faces
可以查看運行結果。
具體程序見示例程序。
另一個方法是實現javax.faces.event.ValueChangeListener接口,并實現其processValueChange()方法。
在jsp中直接用標簽<f:valueChangeListener 引用。見例:
…
<h:form>
<h3><h:outputText
value="#{msgs.hintText}"/></h3>
<h:selectOneMenu
value="#{valueEventBean.locale}"
onchange="this.form.submit();">
<f:valueChangeListener
type="……"/>
<f:selectItem itemValue="zh_TW"
itemLabel="Chinese"/>
<f:selectItem itemValue="en"
itemLabel="English"/>
</h:selectOneMenu>
</h:form>
…
與上面一種的寫法有些區(qū)別,請注意。
這里就不再演示了。
對于動作事件(Action
Event)來說,元件的動作事件是在套用請求值階段就生成ActionEvent物件了,
但相關的事件處理并不是馬上進行,ActionEvent會先被排入佇列,然后必須再通過驗證、更新模式值階段,之后才處理佇列中的事件。
可以設定元件的事件在套用請求值之后立即被處理,并跳過后續(xù)的階段,直接進行畫面繪制以回應請求,
對于JSF的input與command元件,都有一個immediate屬性可以設定,只要將其設定為true,則指定的事件就成為立即事件。
3.JSF Phase 事件
JSF的請求執(zhí)行到回應,完整的過程會經過六個階段:
在每個階段的前后會引發(fā)
javax.faces.event.PhaseEvent,如果您想嘗試在每個階段的前后捕捉這個事件,以進行一些處理,則可以實作
javax.faces.event.PhaseListener,并向javax.faces.lifecycle.Lifecycle登記這個 Listener,以有適當的時候通知事件的發(fā)生。
PhaseListener有三個必須實作的方法getPhaseId()、beforePhase()與afterPhase()
PhaseId.APPLY_REQUEST_VALUES
PhaseId.PROCESS_VALIDATIONS
PhaseId.UPDATE_MODEL_VALUES
PhaseId.INVOKE_APPLICATION
PhaseId.RENDER_RESPONSE
PhaseId.ANY_PHASE
其中PhaseId.ANY_PHASE指的是任何的階段轉換時,都進行監(jiān)聽。
如例:
package
test;
import
javax.faces.event.PhaseEvent;
import
javax.faces.event.PhaseId;
import
javax.faces.event.PhaseListener;
public
class ShowPhaseListener implements PhaseListener {
public void beforePhase(PhaseEvent event)
{
String phaseName =
event.getPhaseId().toString();
System.out.println("++++++++++++Before " + phaseName);
}
public void afterPhase(PhaseEvent event) {
String phaseName =
event.getPhaseId().toString();
System.out.println("++++++++++++After " + phaseName);
}
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}
在faces-config.xml中向Lifecycle進行注冊:
<lifecycle>
<phase-listener>
onlyfun.caterpillar.ShowPhaseListener
</phase-listener>
</lifecycle>
這樣你就可以看到請求運行的每一個階段前后都加上了Log。
具體程序看示例程序。