JavaEE 7教程

JSF入门实战 (2)

上页

Ajax

  JSF提供给网页添加AJAX功能支持。 有两种方法支持:

  • 编程使用JavaScript资源
  • 声明使用F:AJAX


  第一种方式需要使用JSF资源库包中的jsf.js,在页面通过如下激活使用:
<h:body>
<!-- . . . -->
<h:outputScript name="jsf.js" library="javax.faces" target="body"/>
<!-- . . . -->
</h:body>

  对服务器的异步请求:
<h:form prependId="false">
<h:inputText value="#{user.name}" id="name"/>
<h:inputText value="#{user.password}" id="password"/>
<h:commandButton value="Login" type="button" actionListener="#{user.login}"
onclick="jsf.ajax.request(this, event, {execute: 'name password', render: 'status'}); return false;"/>
<h:outputText value="#{user.status}" id="status"/>
</h:form>


  命令按钮有一个ActionListener定义接受异步请求的user这个类的login方法,当单击该按钮时jsf.ajax.request发送异步请求到服务器的User类的login方法。请求分两个部分:execute和render部分,execute是将name和password值通过其对应的组件User的setter方法注入,render是定义异步请求结束后,需要输出的显示部分。

相应的组件user bean如下:
@Named
@SessionScoped
public class User implements Serializable {
 private String name;
 private String password;
 private String status;
. . //ActionListener监听方法. 异步请求调用的方法
 public void login(ActionEvent evt) {
   if (name.equals(password))
     status = "Login successful";
   else
     status = "Login failed";
}
}

使用AJAX更新的案例:
<h:form prependId="false">
  <h:inputText value="#{user.name}" id="name"/>
  <h:inputText value="#{user.password}" id="password"/>

<h:commandButton value="Login" type="button" actionListener="#{user.login}">
<f:ajax execute="name password" render="status"/>
</h:commandButton>
<h:outputText value="#{user.status}"
id="status"/>
</h:form>
输入name password,输出更新status.

可以设置延迟,如果在延迟时间内有多个请求发送,只有最近的请求被发送,其他丢弃。
<f:ajax delay="200" ...>
. . .
</f:ajax>

另外一种写法:
<f:ajax listener="#{user.checkFormat}">
 <h:inputText value="#{user.name}" id="name"/>
 <h:inputText value="#{user.password}" id="password"/>
</f:ajax>
这是异步调用bean的checkFormat方法:
public void checkFormat(AjaxBehaviorEvent evt) {
//. . .
}

验证数据

  如下一个页面:

<h:form>
Name: <h:inputText value="#{myBean.name}"/>
Age: <h:inputText value="#{myBean.age}"/>
Zip: <h:inputText value="#{myBean.zip}"/>
<h:commandButton value="Submit"/>

其对应的Bean可以对输入进行验证,用注解:

@Named
@SessionScoped
public class MyBean implements Serializable {
 @Size(min = 3, message = "At least 3 characters")
 private String name;

 @Min(18)
 @Max(25)
 private int age;

 @Pattern(regexp = "[0-9]{5}")
 private String zip;
//. . .
}

导航规则

  JSF定义了显式和隐式两种导航定义。

  隐式导航:

<h:commandButton action="login" value="Login"/>

点按这个按钮将输出同一个目录下的login.xhtml。

  在faces-config.xml中显式使用<navigation-rule>:

<navigation-rule>
 <from-view-id>/index.xhtml</from-view-id>
  <navigation-case>
   <from-outcome>success</from-outcome>
   <to-view-id>/login.xhtml</to-view-id>
   <if>#{user.isPremium}</if>
  </navigation-case>
</navigation-rule

如果user.isPremium为真,那么从index.xhtml导航到login.xhtml页面。

Faces Flow流

  face流提供了相关的页面和相应的后台bean封装作为一个模块,该模块具有良好可以定义的入口和出口,设计一个face流场景是:用户完成一个任务需要在多个不同的视图输入,比如购物车功能,不断在不同商品页面挑选加入同一个购物车,然后下订单,支付等流程。