2025-03-25

序言
  本文起因是因為使用PrimeFaces,既驚嘆於炫酷的各種UI Components,又因為遇到困難但是社區很少支持而苦惱。回想使用JSF的這些年,從ICEFaces到PrimeFaces,JSF的開源社區都忙於商業支持,而很少對free的用戶進行友好及時的支持。
  <<The Complete Reference-Java Server Faces2.0>>一書提到如果有別人已經造好的車輪子,就沒有必要自己造車輪。是的,一般情況下,都是這樣。但是在JSF的世界裡,在我們很難獲得開源社區的支持的現實下,自己制造車輪子,一方面為瞭自己用,另一方面也是為瞭更好的理解JSF和其他開源庫,第三方的JSF庫有問題自己能夠解決,而不必依賴別人。
  本文所有代碼采用技術:Maven3,Emacs和JDEE(你也可以使用其他文本編輯器如VI),JSF選用標準實現Mojarra 2.0.3-b03,GlassFishV3.0.1,在UBuntu10.10下開發。
  本文參考資料主要來自<<The Complete Reference-Java Server Faces2.0>>一書,以及http://www.mkyong.com/jsf2/custom-tags-in-jsf-2-0


說明
  為瞭和主流JSF的術語一致,有些我采用英文而不翻譯。
UIComponent                 JSF tag後臺對應的類
UI Component                JSF tag以及後臺對應的所有類和配置文件形成的整體
Composite Component    JSF2提供瞭Composite Component的創建方法,避免瞭通過Java代碼生成html標記的繁瑣,隻需要基於現有的JSF tag進行組合即可。但是為瞭學習JSF的內部機制,還是很有必要編寫傳統的Non Composite Component。


第一部分 簡單的Noncomposite Component
運行mvn archetype:generate 出現很多jsf的模板工程選擇,但是沒有一個是我很滿意的,所以隻能自己創建一個簡單的jar包項目。
mvn archetype:generate -DgroupId=com.freebird -DartifactId=jsfex -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
好,現在Maven創建瞭一個工程,目錄為jsfex,我修改pom.xml如下:
<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.freebird</groupId>
  <artifactId>jsfex</artifactId>
  <packaging>jar</packaging>
  <version>1.0</version>
  <name>jsfex</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>0.9.27</version>
    </dependency>
  </dependencies>
</project>


註意,在src/main/resources/建立META-INF目錄,把helloworld.taglib.xml文件放在裡面,打包的時候會自動放到target目錄下jar文件內的META-INF目錄下面。helloworld.taglib.xm文件內容:
<?xml version=1.0 encoding=UTF-8?>
<facelet-taglib xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd” version=”2.0″>
  <namespace>http://com.freebird/jsfex</namespace>
  <tag>
    <tag-name>helloworld</tag-name>
    <component>
      <component-type>HtmlHelloWorld</component-type>
    </component>
  </tag>
</facelet-taglib>


再放入faces-config.xml文件,內容如下:
<?xml version=”1.0″ encoding=”utf-8″?>
<faces-config version=”2.0″ xmlns=”http://java.sun.com/xml/ns/javaee”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd”>
  <component>
    <component-type>HtmlHelloWorld</component-type>
    <component-class>com.freebird.component.HtmlHelloWorld</component-class>
  </component>
</faces-config>


據說annotation可以避免在faces-config.xml文件中配置compoent信息,但是我隻在代碼寫在web應用程序中的時候成功過,當將我的tag獨立打包的時候,總是提示找不到類。這個解決方案可能通過下面這篇文章解決,我沒有試過,提供一個URL地址:
http://ocpsoft.com/opensource/create-common-facelets-jar/


現在實現UIComponent類,代碼如下:


package com.freebird.component;


import javax.faces.component.UIComponentBase;
import javax.faces.context.ResponseWriter;
import java.io.IOException;
import javax.faces.context.FacesContext;
import java.util.Date;


/**
  * Describe class HtmlHelloWorld here.
  *
  *
  * Created: Mon Dec 27 14:39:47 2010
  *
  * @author <a href=”chenshumailto:chenshu@csdesktop”>chenshu</a>
  * @version 1.0
  /
public class HtmlHelloWorld extends UIComponentBase {


  @Override
  public String getFamily() {
    return null;
  }


  @Override
  public void encodeAll(FacesContext context) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement(“p”, this);
    writer.writeAttribute(“style”, “color : red”, null );
    writer.writeText(“HelloWorld! today is: ” + new java.util.Date(), null);
    writer.endElement(“p”);
  }


}


 


好瞭,現在把這個jar包放到一個JSF2的應用中試試看。這裡不再介紹如何編寫JSF2應用程序,已經超出本文范圍。用Maven編寫一個JSF2的應用程序又需要不少步驟,因為我沒有發現我喜歡的模板,得自己從頭定制,我使用的是PrimeFaces,MyBatis,將來還要用Spring3.會在另外的文章中介紹。
首先註冊自己的jar包,用如下命令:
mvn clean install
mvn install:install-file -Dfile=target/jsfex-1.0.jar -DgroupId=com.freebird -DartifactId=jsfex -Dversion=1.0 -Dpackaging=jar


在需要使用的web應用程序中隻需要在pom.xml中加入下面的配置:
    <dependency>
      <groupId>com.freebird</groupId>
      <artifactId>jsfex</artifactId>
      <version>1.0</version>
    </dependency>


facelets頁面上如下使用:
<html…
xmlns:cs=”http://com.freebird/jsfex”/>

<h:f

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *