JSF事件监听器–动作,阶段,值更改
JSF事件和侦听器模型基于JavaBeans规范。
事件定义为基于用户操作(例如单击按钮,超链接,更改输入值等)触发的信号。
JSF告诉组件调用处理用户生成的事件的适当侦听器类。
现在让我们详细了解事件类和侦听器接口。
JSF事件类
与JSF事件相关的类在javax.faces.event包中定义。
在JSF中实现事件类时,必须扩展javax.faces.event包。
可以通过调用event.getComponent来获得生成的事件。
UIComponent ui = new UIComponent(); MyFacesEvent ev1 = new MyFacesEvent(ui); UIComponent sc1 = ev1.getComponent();
通过使用queue()方法,事件可以在请求处理生命周期结束时排队。
可以使用以下代码在特定阶段进行排队
MyFacesEvent ev1 = new MyFacesEvent(); ev1.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
在上面的代码中,事件将在流程验证阶段结束时发生。
JSF侦听器类
事件与所有事件的侦听器类相关联。
例如,如果事件是一个valuechange事件,则将相应的侦听器类" ValueChangeListener"与其关联。
类似地," ActionListener"用于动作事件。
JavaBeans规范使方法成为注册事件的特定侦听器的必需方法。
例如,如果事件名称为" MyOwnEvent",侦听器类为" MyOwnListener",并希望在" MyOwnComponent"上调用此事件,则必须定义以下方法来注册侦听器类。
public void addMyOwnComponentListener(MyOwnListener l1) public void removeMyOwnListener(MyOwnListener l1) public void MyOwnListener[] getMyOwnListeners()
JSF活动
JSF事件属于以下三类之一:
- 动作事件
- 值变化事件
- 阶段事件
JSF动作事件
动作事件是为ui组件(如命令按钮或者命令超链接)生成的事件。
一个事件可以附加任意数量的侦听器。
考虑提交表单的示例。
如下所示创建一个JSF视图页面" mobile.xhtml"。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Text fields</title>
</h:head>
<h:body>
<h3>Mobile details</h3>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel for="mname">Company Name:</h:outputLabel>
<h:inputText id="mname"></h:inputText>
<br
<br
<h:outputLabel for="model">Model Number:</h:outputLabel>
<h:inputText id="model"></h:inputText>
<br
<br
<h:outputLabel for="color">Color:</h:outputLabel>
<h:inputText id="color"></h:inputText>
<br
<br
<h:commandButton value="Mobile Action Listener"
actionListener="#{mobileActionListener.processAction}"
</h:panelGrid>
</h:form>
</h:body>
</html>
其中我们定义属性" actionListener",调用" MobileActionListener"类的processAction方法。
创建MobileActionListener.java类为;
package com.theitroad.jsf.beans;
import javax.faces.FactoryFinder;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
@ManagedBean
@SessionScoped
public class MobileActionListener implements ActionListener {
public MobileActionListener() {
}
@Override
public void processAction(ActionEvent ae) throws AbortProcessingException {
UIComponent ui = ae.getComponent();
System.out.println("Event source is" + ui.getClass().getName());
}
public void listAllPhaseListeners() {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle applicationLifecycle = lifecycleFactory
.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
PhaseListener phaseListeners[] = applicationLifecycle
.getPhaseListeners();
for (PhaseListener phaseListener : phaseListeners) {
System.out.println(phaseListener.getPhaseId());
}
}
}
其中我们实现了ActionListener类,并覆盖了processAction方法。
在此方法内部,我们仅打印由用户调用的事件。
ui.getClass()。
getName()方法输出触发的动作事件。
在" faces-config.xml"文件中进行以下输入,以调用actionlistener类。
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="https://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<managed-bean>
<managed-bean-name>mobileActionListener</managed-bean-name>
<managed-bean-class>
com.theitroad.jsf.beans.MobileActionListener
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<lifecycle>
<phase-listener>
com.theitroad.jsf.beans.CustomPhaseListener
</phase-listener>
</lifecycle>
</faces-config>
受管Bean Mobile Action Listener类路径在faces-config.xml文件中指定。
现在运行该应用程序,并在浏览器中转到mobile.xhtml页面,然后单击提交按钮,这将在控制台中产生以下输出
Event source is javax.faces.component.html.HtmlCommandButton
由于提交按钮是触发的事件,因此该事件是CommandButton标记,与提交按钮相对应。
JSF价值变更事件
值更改事件是指UI组件的文本字段,单选按钮,列表框等。
值更改事件将在UI组件中更改后立即触发。
此事件的侦听器通常根据要求在字段上执行验证,以检查输入的值是否有效。
考虑下面的示例,该示例在列表框中更改值并显示新值
创建mobilevalue.xhtml为;
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core">
<h:head>
<title>Value Change Event</title>
</h:head>
<h:body>
<h3>Value Change Event Example</h3>
<h:form>
<h:panelGrid columns="3">
<h:selectOneMenu id="name" value="#{mobileValueChangeListener.name}"
onchange="submit()"
valueChangeListener="#{mobileValueChangeListener.onSelectNames}">
<f:selectItem itemValue="Nokia" itemLabel="Nokia"
<f:selectItem itemValue="Samsung" itemLabel="Samsung"
<f:selectItem itemValue="Blackberry" itemLabel="Blackberry"
<f:selectItem itemValue="Sony" itemLabel="Sony"
<f:selectItem itemValue="Mi3" itemLabel="Mi3"
</h:selectOneMenu>
</h:panelGrid>
</h:form>
<br
<br
<h:outputText value="#{mobileValueChangeListener.result}"></h:outputText>
</h:body>
</html>
其中我们调用valueChangeListener属性,并调用MobileValueChangeListener bean的onSelectNames方法。
创建MobileValueChangeListener.javabean为;
package com.theitroad.jsf.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
@ManagedBean
@SessionScoped
public class MobileValueChangeListener {
private String name;
private String result;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public MobileValueChangeListener() {
}
public void onSelectNames(ValueChangeEvent vc) {
Object oval = vc.getOldValue();
Object nval = vc.getNewValue();
System.out.println("oval" + oval);
System.out.println("nval" + nval);
if (nval != null) {
result = "Newly changed value is:" + (String) nval;
}
}
}
在onSelectNames方法中,我们通过getOldValue和getNewValue方法获取新值和旧值,并检查新值是否不等于null,如果为true,则将新值存储到结果变量中,并在JSF视图上显示此变量的值。
页。
现在,运行在更改列表框中的值时产生以下输出的应用程序。
JSF阶段事件
这种类型的事件涉及在每个阶段的开始或者结束时在JSF生命周期的六个阶段之一中触发的事件。
考虑一个通过创建CustomPhaseListener.java来捕获阶段事件的示例;
package com.theitroad.jsf.beans;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class CustomPhaseListener implements PhaseListener {
private static final long serialVersionUID = -1395570878923714114L;
@Override
public void afterPhase(PhaseEvent pe) {
System.out.println("After phase" + pe.getPhaseId());
}
@Override
public void beforePhase(PhaseEvent pe) {
System.out.println("Before phase" + pe.getPhaseId());
}
@Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}
创建一个JSF视图页面" phaseListener.xhtml"为;
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="https://www.w3.org/1999/xhtml" xmlns:f="https://java.sun.com/jsf/core" xmlns:h="https://java.sun.com/jsf/html"> <h:head> <title>Phase Listener example</title> </h:head> <h:body> <h3>Phase Listener example</h3> <h:form> <h:inputText id="mname" <h:commandButton id="button" value="Submit" <h:messages </h:form> </h:body> </html>
现在运行该应用程序,并在phaseListener页面上输入一些文本,然后单击Submit按钮。
检查服务器日志,并产生以下输出。
Before phase RESTORE_VIEW 1 After phase RESTORE_VIEW 1 Before phase APPLY_REQUEST_VALUES 2 After phase APPLY_REQUEST_VALUES 2 Before phase PROCESS_VALIDATIONS 3 After phase PROCESS_VALIDATIONS 3 Before phase UPDATE_MODEL_VALUES 4 After phase UPDATE_MODEL_VALUES 4 Before phase INVOKE_APPLICATION 5 After phase INVOKE_APPLICATION 5 Before phase RENDER_RESPONSE 6 After phase RENDER_RESPONSE 6
每个阶段的事件ID都打印在控制台中。

