当用户和代表命令或某操作(gesture)等控件发生交互的时候,触发 动作事件(action event)。产生动作事件的组件也叫做动作源,包括了按钮、超链接等组件。动作事件由动作监听器(action listener)进行处理。

有两种典型的监听器:一种会影响到页面间的导航(navigation),另一种不会影响到导航。影响到页面间导航的监听器主要是处理一些业务逻辑并返回几个业务逻辑结果,JSF的导航系统将会根据这个来选择恰当的下一个页面(译注:并非传统所说的TRUE/FALSE这两种“逻辑”结果,这里讲的是“业务逻辑”,可以是任意的有代表意义的结果。)不影响导航的事件监听器用来操作当前页面内的组件,或者是进行一些业务模型上的改变,或者是修改backing bean的属性等,并不会出现在页面间的跳转。

在技术上,所有页面间导航都是由一个单一的动作监听器来处理。这个监听器自动处理组件所触发的所有事件(event),因此,该监听器并不需要手动地注册/绑定(register)。缺省情况下,这个监听器会将所有的工作交由你制定的backing bean中的某个方法(method)来处理。因此,你可以用不同的方法来处理你程序中的各个业务部分。典型地,你的大多数业务逻辑都将会交由这些方法来处理。

当某个组件触发一个事件的时候,缺省的监听器就决定了该事件的处理结果,该结果用一个字符串(string)来表示,比方说:"success"、"failure" 等。这个结果也可以分为静态和动态两类。静态的是在编码的时候就已经定义好了的例如:
<h:commandButton type="submit" value="Login" action="success" immadiate="true" />
在这个例子当中,当用户点击这个标为Login的按钮的时候,会产生 "success" 这个业务结果并同时触发该按钮被点击这个事件,但是,并没有相应的方法来处理这个事件。

而动态的结果就是由处理该事件的方法所返回的,一个字符串。一个方法可能会返回多个不同的结果,这取决于业务逻辑。动作监听器会自动查找你在该组件的 action 属性中指定的方法,并执行。我们用 EL(expression language) 来指定该属性值。下面是一个 HtmlCommandButton 的实际例子:
<h:commandButton type="submit" value="Login" action="#{user.login}" />
当用户点击该按钮,一个代表该按钮被点击的事件产生,并执行下面的事件处理方法:


1 
 
public 
   
 class 
  User 
 
 
 {
 2 

 3 
   public  String login() 
{
 4 
     if (
) 
{  // 登陆成功 
 5 
       return   " success " ;
 6 
    }else 
{  // 登陆失败 
 7 
       return   " failure " ; 
 8 
    }
 9 
  }
10 

11 
}


login方法的返回值取决于不同的业务逻辑,这里暂不讨论。类User 是一个 backing bean 它的某些属性值和页面上的某些输入控件的值相关联。 而该类会在 faces-config.xml 中有相应的定义。

上面的例子中仅有 "success"、"failure" 等返回值,但是,实际应用中,你的程序可能要求你能操纵JSF组件、业务模型对象、添加消息等等。甚至是 实现页面的直接跳转、输出某个适当响应、和数据库 EJB 等组件 服务等实现交互 等等复杂的功能。动作监听器根据方法的返回值和导航系统中的定义来决定页面跳转。

当你需要执行业务逻辑又不需要页面的跳转的时候,你可以给组件绑定一个 动作监听器方法(action listener method),有别于动作方法(action method),该方法除了可以绑定事件,还可以操纵组件。我们看下面的例子:
<h:commandButton id="redisplayButton" type="submit" value="Redisplay" actionListener="#{loginForm.doIt()}" />
和前面的例子一样,当用户点击该按钮,有事件产生。但是,这次,动作监听器方法得到执行,而不是先前的动作方法。


1  
public    
 void 
  doIt(ActionEvent event) 
 
  {
2 
  HtmlCommandButton button  =  (HtmlCommandButton)event.getComponent();
3 
  button.setValue( " Try again! " );
4 
}


该方法会改变先前点击的按钮的标题,虽然这并没有多少用处。但重要的是,这个方法的签名。他接受了一个 ActionEvent 类的参数,并没有返回值。这,就是 action listener method 和 action method 的主要区别!在前面的方法执行完以后,页面会被刷新,以显示效果。

通常,用 action listener method 方法来执行对当前页面的改变。比方说 value-changing 事件等,你也可以用一个接口来实现,然而,在大多数情况下,用 backing bean 中的方法来实现就已经足够了。