随着JSF2规范通过,JSF2已经慢慢进入我们的视线,本系列以Sun 推荐实现JSF2-Mojarra 为基础,来深入浅出看看JSF2给我们带来了什么。
  首先看看最酷的特性,支持AJAX。
  JSF是基于组件的web Framework,本身有生命周期控制,在JSF1.2的Spec中,没有支持AJAX,而为了提高Web的可用性,AJAX又是必须的。怎么做呢?Oracle的ADF Faces ,Apache 的MyFaces 以及IceFaces等个自有各自的实现,其中ADF Faces和MyFace提出 PPR(Partial Page Rendering)局部渲染技术,其实在本质上就是AJAX。 通过一个事件比如CommandButton CommandLink 等刷新局部需要更改的页面,而不是整个页面。这些实现虽然能够解决问题,但毕竟不是规范不是统一的实现,导致JSF的开发学习成本提高。JSF2面对这种局面,在规范中明确指出JSF2支持AJAX。
        下面的例子来自Mojarra Samlple,看看JSF2中AJAX的使用:
    
1. 准备条件:
     从https://javaserverfaces.dev.java.net下载jSF2 jsf-api.jar  jsf-impl.jar
2.  选择熟悉的IDE和JEE 服务器,本文为Eclipse 和JBoss。
3.  创建Web工程,导入jsf-api.jar  jsf-impl.jar到lib中。
4.  拷贝samples\basic-ajax
5.  Run count.xhtml
分析AJAX调用:
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml"
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html">
      xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
<h:head>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
 <title>Ajax</title>
    <title>Ajax</title>
 </h:head>
</h:head>
 <h:body>
<h:body>
 <h:form id="form1" prependId="false">
    <h:form id="form1" prependId="false">
 <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
        <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
 <h:outputStylesheet name="stylesheet.css"/>
        <h:outputStylesheet name="stylesheet.css"/>
 <h:outputText id="out1" value="#{count.count}"/>
        <h:outputText id="out1" value="#{count.count}"/>
 <br/>
        <br/>
 <h:outputText id="test1" value="otherValue"/>
         <h:outputText id="test1" value="otherValue"/>
 <h:outputText id="test" value="#{count.countStr}"/>
         <h:outputText id="test" value="#{count.countStr}"/>
 <br/>
        <br/>
 <!-- Increment the counter on the server, and the client -->
        <!-- Increment the counter on the server, and the client -->
 <h:commandButton id="button1" value="Count"
        <h:commandButton id="button1" value="Count"
 onclick="jsf.ajax.request(this, event, {execute: this.id, render: 'out1'}); return false;"/>
                         onclick="jsf.ajax.request(this, event, {execute: this.id, render: 'out1'}); return false;"/>
 <br/>
        <br/>
 <!-- Resets the counter, doesn't refresh the page -->
        <!-- Resets the counter, doesn't refresh the page -->
 <h:commandButton id="reset" value="reset"
        <h:commandButton id="reset" value="reset"
 onclick="jsf.ajax.request(this, event, {execute:'reset', render: 'out1'}); return false;"
                            onclick="jsf.ajax.request(this, event, {execute:'reset', render: 'out1'}); return false;"
 actionListener="#{count.reset}"/>
                            actionListener="#{count.reset}"/>
 <h:messages/>
        <h:messages/>
 </h:form>
    </h:form>
 
  
 </h:body
</h:body JSF2使用XHTML来表示页面。在页面中,引入jsf.js. 然后在button1的Onlick事件中AJAX请求Server  jsf.ajax.request(this, event, {execute: this.id, render: 'out1'}). 点击后,仅仅刷新 id为out1d的outputText组件,而不是真个页面。
看看BackBean的代码:
 package net.blogjava.vincent.basicajax;
package net.blogjava.vincent.basicajax;

 import javax.faces.event.ActionEvent;
import javax.faces.event.ActionEvent;
 import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedBean;
 import javax.faces.bean.SessionScoped;
import javax.faces.bean.SessionScoped;
 import java.io.Serializable;
import java.io.Serializable;

 @ManagedBean(name = "count")
@ManagedBean(name = "count")
 @SessionScoped
@SessionScoped

 public class Count implements Serializable {
public class Count implements Serializable {

 private static final long serialVersionUID = 6499154494910177344L;
    private static final long serialVersionUID = 6499154494910177344L;    

 Integer count = 0;
    Integer count = 0;
 String  countStr="";
    String  countStr="";
 
    

 public String getCountStr(){
    public String getCountStr(){
 
        
 return ""+count;
     return ""+count;
 }
    }


 public Integer getCount() {
    public Integer getCount() {
 return count++;
        return count++;
 }
    }


 @SuppressWarnings({"UnusedDeclaration"})
    @SuppressWarnings({"UnusedDeclaration"})

 public void reset(ActionEvent ae) {
    public void reset(ActionEvent ae) {
 count = 0;
        count = 0;
 }
    }
 }
}首先看到JSF2 不需要XML配置文件,通过注释指定Backeban 名字已经Sceope。
当点击button1,局部刷新id为out1d的outputText组件,而id 为test的outputText不会变化。真正做多局部刷新,如下图:

点击CountButton时,第一个OutputText 值一直在曾加,而下面的没有变化,而真个页面刷新时,两个值在变化。
总结:
       通过及其简单的例子说明了JSF2 AJAX特性。我们也可通过该特性实现很炫的功能。相对于PPR,该实现更自由,我们一个在任何组件上调用AJAX,而不像目前PPR只在先对几个组件上。 未完 接下来的更精彩!!