1.JSF動(dòng)作事件
前面的例子,我們直接將按鈕的action綁定到一個(gè)Bean的方法上。實(shí)際上當(dāng)按鈕被觸發(fā)時(shí),JSF會(huì)自動(dòng)產(chǎn)生一個(gè)Listener來(lái)處理事件。
如果您需要使用同一個(gè)方法來(lái)應(yīng)付多種事件來(lái)源,并想要取得事件來(lái)源的相關(guān)訊息,您可以讓處理事件的方法接收一個(gè)javax.faces.event.ActionEvent事件參數(shù)。
如下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動(dòng)作事件--按鈕觸發(fā)的Listener事件,會(huì)在后臺(tái)打出log。</h3>
<h:commandButton value="#{msgs.commandText}">
<f:actionListener
type="test.LogHandler"/>
</h:commandButton>
</f:form>
</f:view>
</body>
</html>
生成一個(gè)自定義的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+++++++++");
}
}
當(dāng)按鈕觸發(fā)時(shí),便會(huì)激活LogHandler這個(gè)Listener。你也可以同時(shí)指定多個(gè)Listener。
http://localhost:8080/jsfTest/pages/jsfMyActionEvent.faces
就可以看到運(yùn)行結(jié)果了。
具體程序參看示例程序。
2.JSF變量/值變事件
如果使用者改變了JSF輸入元件的值后送出表單,就會(huì)發(fā)生值變事件(Value
Change Event),這會(huì)丟出一個(gè)javax.faces.event.ValueChangeEvent物件。
如果您想要處理這個(gè)事件,有兩種方式,一是直接 設(shè)定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,其作用是在選項(xiàng)項(xiàng)目發(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中注冊(cè)Bean。
http://localhost:8080/jsfTest/pages/jsfMyValueEvent.faces
可以查看運(yùn)行結(jié)果。
具體程序見示例程序。
另一個(gè)方法是實(shí)現(xiàn)javax.faces.event.ValueChangeListener接口,并實(shí)現(xiàn)其processValueChange()方法。
在jsp中直接用標(biāo)簽<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ū)別,請(qǐng)注意。
這里就不再演示了。
對(duì)于動(dòng)作事件(Action
Event)來(lái)說(shuō),元件的動(dòng)作事件是在套用請(qǐng)求值階段就生成ActionEvent物件了,
但相關(guān)的事件處理并不是馬上進(jìn)行,ActionEvent會(huì)先被排入佇列,然后必須再通過(guò)驗(yàn)證、更新模式值階段,之后才處理佇列中的事件。
可以設(shè)定元件的事件在套用請(qǐng)求值之后立即被處理,并跳過(guò)后續(xù)的階段,直接進(jìn)行畫面繪制以回應(yīng)請(qǐng)求,
對(duì)于JSF的input與command元件,都有一個(gè)immediate屬性可以設(shè)定,只要將其設(shè)定為true,則指定的事件就成為立即事件。
3.JSF Phase 事件
JSF的請(qǐng)求執(zhí)行到回應(yīng),完整的過(guò)程會(huì)經(jīng)過(guò)六個(gè)階段:
在每個(gè)階段的前后會(huì)引發(fā)
javax.faces.event.PhaseEvent,如果您想嘗試在每個(gè)階段的前后捕捉這個(gè)事件,以進(jìn)行一些處理,則可以實(shí)作
javax.faces.event.PhaseListener,并向javax.faces.lifecycle.Lifecycle登記這個(gè) Listener,以有適當(dāng)?shù)臅r(shí)候通知事件的發(fā)生。
PhaseListener有三個(gè)必須實(shí)作的方法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指的是任何的階段轉(zhuǎn)換時(shí),都進(jìn)行監(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進(jìn)行注冊(cè):
<lifecycle>
<phase-listener>
onlyfun.caterpillar.ShowPhaseListener
</phase-listener>
</lifecycle>
這樣你就可以看到請(qǐng)求運(yùn)行的每一個(gè)階段前后都加上了Log。
具體程序看示例程序。