jsf中有动作事件、即时事件、值变事件、Phase事件四种事件.
下面将一一说明:
动作事件:
通过ActionListener来监听动作事件
先来看一段简单的jsf页面代码:
<h:commandButton value="送出" action="#{user.verify}"/>
以上代码中虽然没有涉及ActionListener,但jsf为其默认产生了预定义的ActionListener.
实际过程是这样:
JSF会先检查是否有指定的actionListener,然后再检查是否指定了动作方法并为其产生预定义的ActionListener,并根据其传回值导航页面.
动作事件三种触发方法:
方法一: 通过指定动作方法
<h:commandButton value="送出" action="#{user.verify}"/>
方法二: 通过指定ActionListener属性
<h:commandButton value="送出" actionListener="#{user.verify}" action="#{user.outcome}"/>
方法三: 通过<f:actionListener>标签向组件注册事件
• LogHandler.java
package onlyfun.caterpillar;
import javax.faces.event.ActionListener;
....
public class LogHandler implements ActionListener {
public void processAction(ActionEvent e) {
// 处理Log
}
}
• VerifyHandler.java
package onlyfun.caterpillar;
import javax.faces.event.ActionListener;
....
public class VerifyHandler implements ActionListener {
public void processAction(ActionEvent e) {
// 处理验证
}
}
<h:commandButton value="送出" action="#{user.outcome}">
<f:actionListener type="onlyfun.caterpillar.LogHandler"/>
<f:actionListener type="onlyfun.caterpillar.VerifyHandler"/>
</h:commandButton>
即时事件:
所谓的即时事件(Immediate Events),是指JSF视图组件在取得请求中该取得的值之后,即立即处理指定的事件,而不再进行后续的转换器处理、验证器处理、更新模型值等流程。
在JSF的事件模型中之所以会有所谓即时事件,是因为Web应用程序的先天特性不同于GUI程序,所以JSF的事件方式与GUI程序的事件方式仍有相当程度的不同,一个最基本的问题正因为HTTP无状态的特性,使得Web应用程序天生就无法直接唤起服务器端的特定对象。
所有的对象唤起都是在服务器端执行的,至于该唤起什么对象,则是依一个基本的流程:
重建视图(Restore View)
依客户端传来的session数据或服务器端上的session数据,重建JSF视图组件。
套用请求值(Apply Request Values)
JSF视图组件各自获得请求中的属于自己的值,包括旧的值与新的值。
执行验证(Process Validations)
转换为对象并进行验证。
更新模型值(Update Model Values)
更新Bean或相关的模型值。
唤起应用程序(Invoke Application)
执行应用程序相关逻辑。
绘制响应页面(Render Response)
对先前的请求处理完之后,产生页面以反应客户端执行结果。
对于动作事件(Action Event)来说,组件的动作事件是在套用请求值阶段就生成ActionEvent对象了,但相关的事件处理并不是马上进行,ActionEvent会先被排入队列,然后必须再通过验证、更新方式值阶段,之后才处理队列中的事件。
这样的流程对于按下按钮然后执行后端的应用程序来说不成问题,但有些事件并不需要这样的流程,例如只影响页面的事件。
举个例子来说,在表单中可能有使用者名称、密码等栏目,并提供有一个地区选项按钮,使用者可以在不填写名称、密码的情况下,就按下地区选项按钮,如果依照正常的流程,则会进行验证、更新模型值、唤起应用程序等流程,但显然的,使用者名称与密码是空白的,这会引起不必要的错误。
您可以设定组件的事件在套用请求值之后立即被处理,并跳过后续的阶段,直接进行页面绘制以响应请求,对于JSF的input与command组件,都有一个immediate属性可以设定,只要将其设定为true,则指定的事件就成为即时事件。
一个例子如下:
• 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=UTF8"%>
<f:view locale="#{user.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:outputText value="#{msgs.nameText}"/>:
<h:inputText value="#{user.name}"/><p>
<h:outputText value="#{msgs.passText}"/>:
<h:inputSecret value="#{user.password}"/><p>
<h:commandButton value="#{msgs.commandText}"
action="#{user.verify}"/>
<h:commandButton value="#{msgs.Text}"
immediate="true"
actionListener="#{user.changeLocale}"/>
</h:form>
</body>
</html>
</f:view>
这是一个可以让使用者决定使用语系的示范,最后一个commandButton组件被设定了immediate属性,当按下这个按钮后,JSF套用请求值之后会立即处理指定的actionListener,而不再进行验证、更新模型值,需要注意的是,此时您在输入栏目与密码栏目中填入的值,不会影响您的user.name与user.password。
值变事件
如果使用者改变了JSF输入组件的值后提交表单,就会发生值变事件(Value Change Event),这会丢出一个javax.faces.event.ValueChangeEvent对象,如果您想要处理这个事件,有两种方法:
方法一 直接设定JSF输入组件的valueChangeListener属性,例如:
<h:selectOneMenu value="#{user.locale}"
onchange="this.form.submit();"
valueChangeListener="#{user.changeLocale}">
<f:selectItem itemValue="zh_CN" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
注意在此为了模拟GUI中选择了选单项目之后就立即发生反应,我们在onchange属性中使用了JavaScript,其作用是在选项项目发生改变之后,立即提交表单,而不用按下提交按钮
方法二 实现javax.faces.event.ValueChangeListener接口,并定义其processValueChange()方法,例如:
• SomeListener.java
package onlyfun.caterpillar;
....
public class SomeListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) {
....
}
....
}
然后在JSF页面上使用<f:valueChangeListener>标签,并设定其type属性,例如:
<h:selectOneMenu value="#{user.locale}"
onchange="this.form.submit();">
<f:valueChangeListener
type="onlyfun.caterpillar.SomeListener"/>
<f:selectItem itemValue="zh_CN" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
Phase事件
在即时事件中我们提到,JSF的请求执行到反应,完整的过程会经过六个阶段.
在每个阶段的前后会引发javax.faces.event.PhaseEvent,如果您想尝试在每个阶段的前后捕捉这个事件,以进行一些处理,则可以实现javax.faces.event.PhaseListener,并向javax.faces.lifecycle.Lifecycle登记这个Listener,以在适当的时候通知事件的发生。
PhaseListener有三个必须实现的方法getPhaseId()、beforePhase()与afterPhase(),其中getPhaseId()传回一个PhaseId对象,代表Listener想要被通知的时机,可以设定的时机有:
PhaseId.RESTORE_VIEW
PhaseId.APPLY_REQUEST_VALUES
PhaseId.PROCESS_VALIDATIONS
PhaseId.UPDATE_MODEL_VALUES
PhaseId.INVOKE_APPLICATION
PhaseId.RENDER_RESPONSE
PhaseId.ANY_PHASE
其中PhaseId.ANY_PHASE指的是任何的阶段转换时,就进行通知;您可以在beforePhase()与afterPhase()中编写阶段前后编写分别想要处理的动作,例如下面这个简单的类会列出每个阶段的名称:
• ShowPhaseListener.java
package onlyfun.caterpillar;
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;
}
}
编写好PhaseListener后,我们可以在faces-config.xml中向Lifecycle进行注册:
• faces-config.xml
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<lifecycle>
<phase-listener>
onlyfun.caterpillar.ShowPhaseListener
</phase-listener>
</lifecycle>
......
</faces-config>
分享到:
相关推荐
API JAR文件包含JSF的公共接口和类,允许开发者在应用程序中引用和使用JSF的功能,如创建可重用的UI组件、处理用户事件、数据绑定等。 3. **jsf-impl.jar**:与jsf-api.jar相对应,这个文件包含了JSF的实现代码。在...
JavaServer Faces(JSF)是Java平台上的一种用于构建用户界面的服务器端框架,它简化了Web应用程序的开发,特别是处理用户交互和业务逻辑的集成。JSF提供了组件模型、事件处理和生命周期管理机制,使得开发者可以...
本文将深入探讨JSF 1.2的源码,重点关注`jsf-api`、`jsf-ri`、`jsf-tools`和`jsf-doc`这四个关键部分。 ### 1. `jsf-api` `jsf-api`包含了JSF框架的公共接口和类,这些定义了开发者如何在他们的应用程序中与JSF...
`jsf-api.jar` 文件包含了JSF框架的公共接口和API,它定义了JSF的核心组件、事件处理、渲染器以及生命周期等关键概念。开发者通过导入这个库,可以使用JSF提供的各种接口和类来实现页面组件、监听器和转换器等功能。...
JSF是一种用于构建用户界面的MVC(Model-View-Controller)框架,专为Java EE设计。它简化了Web应用程序的开发,通过组件化的方式,允许开发者快速创建交互式的用户界面。JSF支持多种视图技术,如HTML、XHTML,以及...
* **定义**: JavaServer Faces (JSF) 是一种用于简化Java Web开发的强大且灵活的组件技术。 * **特点**: 采用组件驱动的方法来构建Web应用程序,使得开发过程更为简单直观。 * **适用范围**: 适用于企业级应用开发,...
JSF 1.1是该框架的一个早期版本,它提供了一种组件化的方式来创建交互式的Web界面,同时简化了前后端开发的复杂性。在这个教程中,我们将深入探讨JSF 1.1的基础知识。 **一、JSF架构** JSF的核心概念是组件模型,它...
JSF 还支持数据绑定,事件处理,以及与服务器端的通信。 3. **Flux 架构**:Flux 是 Facebook 为前端 Web 开发提出的一种架构模式,强调单向数据流。它将应用程序分为 Store(存储状态)、Dispatcher(调度器)、...
这四个技术的结合,构建了一个强大的、灵活的和可扩展的应用架构。 JSF(JavaServer Faces)是Java平台上的一个MVC(Model-View-Controller)框架,主要用于构建用户界面。它提供了丰富的组件库和事件处理机制,...
2. **生命周期**:JSF应用有四个主要阶段:恢复视图、应用请求值、处理验证和更新模型值、调用应用逻辑。在这些阶段中,JSF处理用户的输入、验证数据、更新模型,并调用后端业务逻辑。 3. **FacesContext**:JSF...
JavaServer Faces(简称JSF)是Java平台提供的一种用于构建企业级Web应用程序的标准框架。JSF通过定义一套简洁而强大的API来帮助开发者更轻松地开发用户界面。其中,JSF的生命周期管理机制是其核心特性之一,它包括...
JavaServer Faces(JSF)是一种由Sun Microsystems开发的MVC(Model-View-Controller)框架,用于构建J2EE平台上的Web应用程序。JSF的核心理念是通过可重用的服务器端组件来创建用户界面,简化Web应用程序的开发。在...
JSF是一种Java平台上的用户界面组件框架,用于构建和实现Web应用程序。它简化了前端和后端的交互,为开发者提供了丰富的组件库,使得创建动态、数据驱动的网页变得更加便捷。在"JSF开发-学生信息管理系统"中,我们...
7. **Faces Flow**:提供了一种新的导航方式,使得大型应用程序的流程管理更加有序和可维护。 8. **CDI(Contexts and Dependency Injection)集成**:JSF 2.0与CDI(上下文和依赖注入)深度整合,简化了组件的生命...
JSF支持多种类型的事件处理,包括动作事件、即时事件和值变更事件等。 ##### 4.1 动作事件 动作事件是最常见的事件类型之一,通常发生在用户点击按钮或其他交互元素时。开发者可以通过定义ActionListener来处理...
在 JSF 中,动作事件是最常见的一种事件类型。 AnyFo - JSF 九陰真經介绍了如何使用 action 属性来指定动作事件的处理方法,包括直接调用 action 指定的方法、直接指定 actionListener 等。 四、国际化 AnyFo -...
#### 四、事件处理 **4.1 动作事件** 动作事件是用户与UI组件交互时触发的事件,例如按钮点击。这些事件通常会触发特定的方法调用。 **4.2 即时事件** 即时事件是在组件值改变时触发的事件。例如,当用户在...