JAVA開發精彩教程:JSF系列(一)

JAVA開發精彩教程:JSF系列(一) 出處:PConline責任編輯:chenyong
[03-10-21 15:34] 作者:fpwang/Matrix.com
  Java Server Faces(JSF)技術爲開發基於網絡用戶界面的Java開發者提供了標準的編程接口API以及標記庫。Apache Struts框架的作者Craig McClanahan,協助領導了Sun公司的JSF項目。這使項目能夠容易的從流行的Apache向JSF標準移植得到了保證。就像Struts框架一樣,JSF定義了一套JSP標記,能夠生成與JavaBean屬性綁定在一起的HTML表單元素。從應用開發者的角度看,兩種框架是很相似的,但是JSF可能將會得到更多的支持。因爲JSF是Java的標準。在未來的發展中,有可能所有的J2EE應用服務器都需要支持JSF(Java Server Faces)。

  Sun公司在已經發布的免費下載開發包Java Web Services Developer Pack 1.2 ( http://java.sun.com/webservices/downloads/webservicespack.html)中,包括了JSF詳細說明(JSF Specification Version 1.0, Public Review Draft 2)的參考實現(Early Access 4 — EA4)。EA4版本實現了許多新特性:動作、beans管理和導航規則。本文將集中介紹這些新特性以及展示如何從JSF的開發中得到好處以便建立表單,確認用戶輸入以及將用戶界面組件與JavaBean屬性綁定起來。


  本文包含一個由四個主要部分組成的網絡應用:

  1. JavaBean類(PBean.java),作爲數據模型保存一些文本以及相關屬性:字體、大小、 顏色、擺放位置等;

  2. 基於JSF的表單(edit.jsp),使用戶可以爲JavaBean的屬性賦值;

  3. Java類(PBuilder.java),用給定的文本按照其屬性值生成HTML頁面程序;

  4. JSP頁面(view.jsp),顯示生成的HTML頁面。

  注:

  源代碼下載地址: http://www.onjava.com/onjava/2003/09/03/examples/usingjsf-src.zip

  相關文檔

  原文:Introducing JavaServer Faces( http://www.onjava.com/pub/a/onjava/2003/07/30/jsf_intro.html)

  譯文: http://www.matrix.org.cn/forum_view.asp?forum_id=14&view_id=658

  JavaServer Faces(或者叫JSF)是服務端程序開發新的發展趨勢。它可以使你更輕鬆的的設計程序,你的程序也能夠更容易維護,甚至可能還會使你的工作更有趣。Budi Kurniawan向我們展示了JSF技術,解釋了爲什麼JSF如此有用以及它是否實現了所承諾的功能。

圖1:基於JSF的表單

  製作JSF表單

  當你開發網絡應用時,處理HTML表單是最常見的一項任務。一個好的框架能夠節省很多開發時間,因爲許多日常的程序操作可以自動的完成或是減少到最低限度只需要在XML文件中用幾行完成。這也有可能簡化使用JSP標記庫的網絡開發。Java Server Faces框架提供了JSP標記,用於描述表單、管理表單狀態、確認用戶輸入以及報錯、將用戶界面組件與JavaBean屬性綁定在一起以及其他許多可提高開發效率的功能。JSF也有豐富的編程接口可用於建立定製的用戶界面(UI)組件,定製驗證類(驗證器validator)以及服務端的事件監聽器。
JSF包含兩類標記庫分別叫JSF核心庫與HTML基礎庫。前者提供普通的標記和一些用於在用戶界面組件中註冊驗證器以及事件監聽器的標記。後者包含用於描述用戶界面組件的JSP標記,如:按鈕、文本域、複選按鈕、列表等。文件edit.jsp用這些標記建立了表單。兩種標記庫的標準前綴是f和h,並且定義在edit.jsp文件的最前面:
<%@ taglib prefix="f" uri=" http://java.sun.com/jsf/core"; %> <%@ taglib prefix="h" uri=" http://java.sun.com/jsf/html"; %>
<f:use_faces>標記是容器標記,必須包含所有在同一頁面中出現的JSF標記。該標記不會產生任何HTML內容,但是它會觸發JSF的內部機制。<h:form>標記產生能夠包含用戶界面元素的HTML元素<form>。
<html><head><title>Edit</title></head><body> <f:use_faces> <h:form formName="pform"> .......... </h:form></f:use_faces> </body></html>
上面的JSP代碼生成下面的HTML片斷:
<html><head><title>Edit</title></head><body> <form method="post" action="/usingjsf/faces/edit.jsp"> .......... </form></body></html>
  下一部分介紹應用的JavaBean模型。

  管理Bean

  像其他一些Web框架一樣,JSF將用戶界面從封裝數據以及應用邏輯的對象模型中分離出來。當HTML用戶界面由JSF標記產生時,JSF框架從JavaBean模型獲得數據並設置HTML表單用戶界面組件的屬性狀態。用戶提交表單時,JSF驗證用戶輸入,如果全部正常JSF就將用戶輸入保存到JavaBean模型並且HTTP請求會根據“導航規則”進入下一頁面。如果驗證出現錯誤,JSF回到表單並返回錯誤信息,這樣用戶就可以糾正錯誤輸入。
類Pbean遵循JavaBean規範,實現了java.io.Serializable併爲其屬性(文本、大小、字體、顏色、擺放位置、粗體、斜體、下劃線)提供了相應的get及set方法。JSF每一個應用的用戶都創建了一個PBean的實例,該實例存儲在JSP的會話(session)中並在名爲faces-config.xml的XML格式配置文件中指定ID。JSF也會根據faces-config.xml文件提供的數據初始化JavaBean實例的屬性值。該XML文件還可能包含其他JSF配置參數,如:導航規則,我們將在後面的章節介紹。

  下面的XML程序片斷包含由JSF所管理的JavaBean的聲明:
<?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> .......... <managed-bean> <managed-bean-name>pbean</managed-bean-name> <managed-bean-class> com.devsphere.articles.usingjsf.PBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>text</property-name> <null-value/> </managed-property> <managed-property> <property-name>size</property-name> <value>3</value> </managed-property> <managed-property> <property-name>font</property-name> <values> <value>Arial</value> <value>Courier New</value> </values> </managed-property> <managed-property> <property-name>color</property-name> <value>green</value> </managed-property> <managed-property> <property-name>align</property-name> <value>left</value> </managed-property> <managed-property> <property-name>bold</property-name> <value>false</value> </managed-property> <managed-property> <property-name>italic</property-name> <value>true</value> </managed-property> <managed-property> <property-name>underline</property-name> <value>false</value> </managed-property> </managed-bean></faces-config>

由JSF創建的管理bean能夠根據<managed-bean-scope>元素的值而存儲在請求(request)、會話(session)或應用的範圍內。<managed-bean-scope>元素的值可爲空值。如果一個對象已經指定了ID並註冊在給定的範圍內那麼JSF不會建立JavaBean實例。
用戶界面組件與驗證

  文件edit.jsp中的<h:form>元素包含多個用戶界面組件,我們將會在後面詳細地介紹。各組件的HTML代碼都是由JSF組件標記產生,例如:<h:input_textarea>,該標記中可能還會包含其他JSF標記,如:<f:validate_required>標記,該標記使JSF確認用戶輸入了信息。

  處理用戶輸入的組件使用屬性valueRef="pbean.property"與JavaBean屬性綁定起來。JSF獲得和設置管理bean屬性值已在前面介紹了。

  有的JSF組件標記不會處理任何用戶輸入。例如<h:output_text>可用於輸出文本或JavaBean只讀屬性的值。

  每個組件都有唯一的ID,ID可在id屬性中指定或由JSF自動生成。要進行驗證的用戶界面組件需要id屬性以便驗證錯誤能夠與<h:output_errors for="id"/>一起顯示打印出來。

圖2:驗證錯誤
  文本域Text Area

  JSF表單的文本域讓用戶輸入將會由Pbuilder.java生成並由view.jsp顯示的某些文字段落等內容。edit.jsp顯示一個由<h:output_text>確定的標籤並使用<h:input_textarea>生成3行30列的<textarea>HTML元素。<f:validate_required>標記註冊一個JSF驗證器,如果用戶在文本域中的輸入爲空則發出錯誤信號。錯誤信息將顯示在<h:output_errors>標記的位置,除了顯示錯誤外該標記不會做其他任何操作。<h:output_errors>標記的for屬性值與<h:input_textarea>的id屬性值相同。
<f:use_faces> <h:form formName="pform"> <p><h:output_text value="Text:"/><br> <h:input_textarea id="text" valueRef="pbean.text" rows="3" cols="30"> <f:validate_required/> </h:input_textarea> <br><h:output_errors for="text"/> .......... </h:form></f:use_faces>

上面的JSP代碼生成下面的HTML片斷:

<form method="post" action="/usingjsf/faces/edit.jsp"> <p>Text:<br> <textarea name="text" cols="30" rows="3">JavaServer Faces</textarea> <br> ..........</form>

<h:input_textarea>的屬性valueRef="pbean.text"使JSF查找ID爲pbean的JavaBean實例,並且將用戶輸入的文本存儲到JavaBean實例的text屬性中。當HTML的表單被生成後,JSF會將text屬性值插入到<textarea>HTML元素中。類Pbean實現了get和set方法可讓JSF獲得或修改屬性的值:

public class PBean implements java.io.Serializable { private String text; public String getText() { return text; } public void setText(String text) { this.text = text; } .......... }

  除了<h:input_textarea>,JSF還提供了許多生成單行文本域(text field)的標記:

  <intput_text>

  <h:input_number>

  <input_secret>(密碼輸入)

  <input_date>

  <input_datetime>

  <input_time>

  <input_hidden>可被用於隱藏的表單域

  單行文本域(Text Field)

  edit.jsp文件的單行文本域組件只允許輸入1至7之間的數字。由<h:input_number>生成這段HTML代碼,該標記包含兩個驗證器。<f:validate_required>標記在前面已經介紹了。<f:validate_longrange>標記是使驗證器確認用戶輸入的數字在給定的範圍之內。如果超出範圍,則向用戶報告驗證錯誤,錯誤信息由<h:output_errors>產生。

  [code]<f:use_faces>
  <h:form formName="pform">
  ..........
  <p><h:output_text value="Size: [1-7]"/><br>
  <h:input_number id="size" valueRef="pbean.size" size="2">
   <f:validate_required/>
  <f:validate_longrange minimum="1" maximum="7"/>
  </h:input_number>
  <br><h:output_errors for="size"/>
  ..........
  </h:form>
  </f:use_faces>
  [/code]

  上面的JSP代碼生成下面的HTML片斷:
  <form method="post" action="/usingjsf/faces/edit.jsp">
   ..........
  <p>Size: [1-7]<br>
  <input type="text" name="sie" id="size" value="3" size="2">
  <br>
  ..........
  </form>

  單行文本域被定爲size,類型爲整形(int)。size中value屬性的值(3)是表示所生成的HTML表單數字輸入區域的初值。假設沒有出現驗證錯誤,當JSF收到包含新JavaBean size屬性值的用戶輸入就會刷新JavaBean。<h:input_number>標記的size屬性是限定單行文本域的字符長度(2),不會對JavaBean屬性有其他操作。

public class PBean implements java.io.Serializable { .......... private int size; public int getSize() { return size; } public void setSize(int size) { this.size = size; } .......... }

除了<f:validate_required>與<f:validate_longrange>標記,JSF還提供了幾個驗證器標記:
  <validate_doublerange>
  <validate_stringrange>
  <validate_length>
  <validator>

  最後一個爲通用標記,可以用它在用戶界面組件中註冊你自己的定製驗證器。你也能夠創建自己的驗證器標記庫。

  列表List Box

  <h:selectone_listbox>與<h:selectmany_listbox>標記生成HTML元素<select>,網頁瀏覽器會將<select>顯示爲列表。前者允許用戶進行單項選擇,後者用於多項選擇。

  文件edit.jsp使用<h:selectmany_listbox>標記生成一個含有幾個字體名稱的列表。HTML的<option>元素定義列表中的選項,這由JSF標記<h:selectitem>生成:

<f:use_faces> <h:form formName="pform"> .......... <p><h:output_text value="Font:"/><br> <h:selectmany_listbox id="font" valueRef="pbean.font"> <h:selectitem itemvalue="Arial" itemLabel="Arial"/> <h:selectitem itemvalue="Courier New" itemLabel="Courier New"/> <h:selectitem itemvalue="Times New Roman" itemLabel="Times New Roman"/> </h:selectmany_listbox> .......... </h:form></f:use_faces>


  上面的代碼生成下面的HTML片斷:

<form method="post" action="/usingjsf/faces/edit.jsp"> .......... <p>Font:<br> <select name="font" multiple size="3"> <option value="Arial" selected>Arial</option> <option value="Courier New" selected>Courier New</option> <option value="Times New Roman">Times New Roman</option> </select> ..........</form>

  列表被定義爲font,類型爲字符串數組(String[])。第一個getFont()方法使用clone()方法複製內部的數組並將其返回,內部數組必須從外部訪問中得到保護。第一個setFont()方法用clone()方法複製所提供的數組並保存起來,所提供的數組可被第二個setFont()方法修改。

  public class PBean implements java.io.Serializable {

  ..........

  private String fontArray[];

  public String[] getFont() {
  return (String[]) fontArray. clone();
  }

  public void setFont(String fontArray[]) {
  this.fontArray = (String[]) fontArray.clone();
  }

  public String getFont(int index) {
  return fontArray[index];
  }

  public void setFont(int index, String font) {
  if (fontArray == null)
  fontArray = new String[index+1];
  else if (fontArray.length <= index) {
  String oldFontArray[] = fontArray;
  fontArray = new String[index+1];
  for (int i = 0; i < oldFontArray.length; i++)
  fontArray[i] = oldFontArray[i];
  }
  fontArray[index] = font;
  }

  ..........

  }
下拉列表(Drop-Down List)

<h:selectone_menu>標記用於生成包含幾個顏色選項的下拉列表。

<h:selectitem>標記包含在<h:selectone_menu>中,作爲下拉列表的選項:



<f:use_faces> <h:form formName="pform"> .......... <p><h:output_text value="Color:"/><br> <h:selectone_menu id="color" valueRef="pbean.color"> <f:validate_required/> <h:selectitem itemvalue="black" itemLabel="Black"/> <h:selectitem itemvalue="red" itemLabel="Red"/> <h:selectitem itemvalue="blue" itemLabel="Blue"/> <h:selectitem itemvalue="green" itemLabel="Green"/> </h:selectone_menu> <br><h:output_errors for="color"/> .......... </h:form></f:use_faces>


上面的JSP代碼生成下面的HTML片斷:


<form method="post" action="/usingjsf/faces/edit.jsp"> .......... <p>Color:<br> <select name="color" size="1"> <option value="black">Black</option> <option value="red">Red</option> <option value="blue">Blue</option> <option value="green" selected>Green</option> </select> <br> ..........</form>



下拉列表定義爲color,類型爲字符串(String):

public class PBean implements java.io.Serializable { .......... private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } .......... }


當HTML表單被生成時,JSF將HTML屬性selected加入到值與JavaBean模型color屬性相同的列表項中。假設沒有驗證錯誤,JSF收到包含新顏色值的用戶輸入後會刷新JavaBean屬性。
單選鈕(Radio Button)

<h:selectone_radio>與<h:selectitem>標記用於生成一組單選鈕:


<f:use_faces> <h:form formName="pform"> .......... <p><h:output_text value="Alignment:"/><br> <h:selectone_radio id="align" valueRef="pbean.align" layout="LINE_DIRECTION"> <f:validate_required/> <h:selectitem itemvalue="left" itemLabel="Left"/> <h:selectitem itemvalue="center" itemLabel="Center"/> <h:selectitem itemvalue="right" itemLabel="Right"/> </h:selectone_radio> <br><h:output_errors for="align"/> .......... </h:form></f:use_faces>

上面的JSP代碼生成如下代碼:

<form method="post" action="/usingjsf/faces/edit.jsp"> .......... <p>Alignment:<br> <table border="0"> <tr> <td><input type="radio" checked name="align" value="left"> Left</td> &nbp; <td><input type="radio" name="align" value="center"> Center</td> <td><input type="radio" name="align" value="right"> Right</td> </tr> </table> <br> ..........</form>



單選鈕定義爲align:


public class PBean implements java.io.Serializable { .......... private String align; public String getAlign() { return align; } public void setAlign(String align) { this.align = align; } .......... }


HTML表單生成時,JSF將HTML屬性checked加入到與JavaBean模型的align屬性值相同的單選鈕中。假如沒有驗證錯誤,JSF收到新擺放位置的用戶輸入時刷新JavaBean屬性。

複選鈕(Checkbox)

文件edit.jsp包含3個由<h:selectboolean_checkbox>標記生成的複選鈕。這些界面組件包含在由<h:panel_grid>與<h:panel_group>標記生成的表格(table)中:

<f:use_faces> <h:form formName="pform"> .......... <p><h:output_text value="Style:"/><br> <h:panel_grid columns="3" border="0" cellspacing="5"> <h:panel_group> <h:selectboolean_checkbox id="bold" valueRef="pbean.bold"/> <h:output_text value="Bold"/> </h:panel_group> <h:panel_group> <h:selectboolean_checkbox id="italic" valueRef="pbean.italic"/> <h:output_text value="Italic"/> </h:panel_group> <h:panel_group> <h:selectboolean_checkbox id="underline" valueRef="pbean.underline"/> <h:output_text value="Underline"/> </h:panel_group> </h:panel_grid> .......... </h:form></f:use_faces>




上面代碼生成如下片斷:


<form method="post" action="/usingjsf/faces/edit.jsp"> .......... <p>Style:<br> <table border="0" cellspacing="5"> <tr> <td><input type="checkbox" name="bold">Bold</td> <td><input type="checkbox" name="italic" checked>Italic</td> <td><input type="checkbox" name="underline">Underline</td> </tr> </table> ..........</form>



3個複選鈕分別與類型爲布爾(Boolean)的bold、italic、underline綁定在一起:


public class PBean implements java.io.Serializable { .......... private boolean bold; public boolean isBold() { return bold; } public void setBold(boolean bold) { this.bold = bold; } private boolean italic; public boolean isItalic() { return italic; } public void setItalic(boolean italic) { this.italic = italic; } private boolean underline; public boolean isUnderline() { return underline; } public void setUnderline(boolean underline) { this.underline = underline; } .......... }



生成HTML表單時,JSF將checked屬性加入到每一個JavaBean屬性爲真(true)的複選鈕中。假如沒有驗證錯誤,JSF收到用戶輸入後就會刷新JavaBean屬性。



在本例中,複選鈕是分別獨立生成的。JSF也提供了<h:selectmany_checkboxlist>標記用於生成一組複選鈕。還提供了<h:panel_list>和<h:panel_data>兩個標記用於從集合與數組中生成表格。

命令按鈕(Command Buttons)

文件faces-config.xml定義了導航規則,決定JSF在用戶點擊網頁中的命令按鈕時做什麼,網頁的路徑由<from-tree-id>標記(/edit.jsp)指定。由<navigation-case>元素分別定義了兩個導航塊(navigation case):


..........<faces-config> <navigation-rule> <from-tree-id>/edit.jsp</from-tree-id> <navigation-case> <from-outcome>editOutcome</from-outcome> <to-tree-id>/edit.jsp</to-tree-id> </navigation-case> <navigation-case> <from-outcome>viewOutcome</from-outcome> <to-tree-id>/view.jsp</to-tree-id> </navigation-case> </navigation-rule> ..........</faces-config>




文件edit.jsp包含由標記<h:command_button>生成的兩個按鈕。每個都有一個標識(ID)、一個標籤、一個命令名稱(這裏沒有使用,但JSF需要)以及一個action或actionRef屬性:


<f:use_faces> <h:form formName="pform"> .......... <p> <h:command_button id="view" label="View" commandName="viewCmd" action="viewOutcome"/> <h:command_button id="boldUpperCase" label="Bold Upper Case / View" commandName="boldUpperCaseCmd" actionRef="pbean.boldUpperCaseAction"/> </h:form></f:use_faces>




上面JSP代碼生成如下HTML片斷:


<form method="post" action="/usingjsf/faces/edit.jsp"> .......... <p> <input type="submit" name="view" value="View"> <input type="submit" name="boldUpperCase" value="Bold Upper Case / View"></form>



JSF會在每次瀏覽器提交用戶輸入時驗證表單中的數據。如果驗證器沒有發出錯誤信號而且沒有類型轉換錯誤,JSF便會分析導航塊(navigation case)。對於第一個按鈕,JSF會得到action屬性的值viewOutcome,該值與第二個導航塊的<from-outcome>元素中的文本匹配。因此,JSF將HTTP請求轉發給view.jsp,文件view.jsp的路徑包含在第二個導航塊的<to-tree-id>元素中。

當用戶點擊第二個按鈕時,JSF則調用PBean對象的getBoldUpperCaseAction()方法。該方法返回一個BoldUpperCaseAction的實例,BoldUpperCaseAction則是PBean的內部類。接着,JSF調用invoke()方法,該方法返回一個在運行時決定的結果而不是固定不變的HTML文件:

public class PBean implements java.io.erializable { .......... public BoldUpperCaseAction getBoldUpperCaseAction() { return new BoldUpperCaseAction(); } public class BoldUpperCaseAction extends javax.faces.application.Action { public String invoke() { String ucText = getText().toUpperCase(); if (isBold() && getText().equals(ucText)) return "viewOutcome"; else { setBold(true); setText(ucText); return "editOutcome"; } } } }



如果bold(粗體)屬性的值爲true(真)並且文本的所有字符爲大寫的,JSF就按照第二個導航塊中的定義,與另一個按鈕情況一樣JSF將HTTP請求轉發給view.jsp。另外,invoke()方法會將bold屬性設爲true,並將文本的所有字符改爲大寫的,最後返回字符串editOutcome,使JSF按照第一個導航塊的定義,保持edit.jsp爲當前頁。
發佈了23 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章