在本教程中,您將學習 JSF 1.2(Woodstock)中的轉換器和驗證器。轉換器用來將字符串輸入轉換為數據型 Java 數據類型,以達到計算之類的多種目的。驗證器用來核實用戶輸入是否落在指定的范圍內。您將使用 Visual Web JSF 框架來創建一個將溫度從攝氏轉換為華氏的應用程序。該應用程序使用一個轉換器來將用戶輸入從一個字符串值轉換為數值型 Java 數據類型,應用程序就能用它來進行計算。該應用程序還是用一個驗證器來檢查數據是否落在指定的范圍內,並通過一個消息組件來報告驗證錯誤。然後您將生成一個計算貨幣值並顯示格式化的時間值的 Web 應用程序。
您還將學習如何向應用程序添加您自己的驗證處理程序,以及如何在標准驗證失敗時覆蓋由 IDE 提供的內建錯誤消息。
本教程要用以下技術和資源來運作
JavaServer Faces 組件/
Java EE 平台
1.2 和 Java EE 5*1.1 和 J2EE 1.4
Travel 數據庫 非必需* 為利用好 NetBeans IDE 6.0 的 Java EE 5 功能,請使用與 Java EE 5 規范完全兼容的應用服務器,比如 Sun Java Application Server 9 / GlassFish。
本教程被編寫成適用於 GlassFish V2 應用服務器。如果您使用不同的服務器,請查閱發行說明和 FAQ 以了解已知問題和解決辦法。要了解有關受支持的服務器和 Java EE 平台的詳細信息,請參見發行說明。
設計應用程序
在本節中,您將創建應用程序,並向它添加必要的組件。
創建一個 Web 應用程序項目,命名為“ValidatorConverter”。啟用 Visual Web JavaServer Faces 框架。
圖 1 顯示了您將在下列步驟中創建的頁面。
從“組件面板”的“基本”類別,將一個“文本字段”拖放到頁面上。將“label”屬性設為“Celsius”,“text”屬性設置為“0.0”。
“label”和“text”屬性位於“屬性”窗口的“外觀”類別下。text 值是運行時的缺省顯示值。
將文本字段的“required”屬性設為“True”,方法是選中“屬性”窗口中的復選框。
“required”屬性位於“屬性”窗口的“數據”類別下。True 值要求用戶為該輸入字段輸入值。如果用戶沒有輸入值而嘗試提交頁面,就會返回一個標准驗證錯誤消息。Celsius 標簽旁出現一個紅色星號,表明 required 值已被設置。
在頁面上放置一個“標簽”組件。將標簽的文本設為“Fahrenheit”。
在 Fahrenheit 標簽右邊放置一個“靜態文本”組件。將“text”屬性設為“32.0”,代表華氏溫標裡水的冰點。
從“組件面板”的“基本”類別,將一個“消息”組件拖放到 Fahrenheit 標簽下面。
按住 Ctrl+Shift 鍵,從消息組件向文本字段組件拖出一條線。
消息組件的文本變為“textField1 的概要消息”,如下圖所示:
圖 1:概要消息
在下一節中,您將添加一個驗證器以確保用戶的輸入落在指定的范圍裡。
使用驗證器
如果您的應用程序要從用戶收集信息,例如登錄和密碼,那麼核實用戶數據就很重要。IDE 提供了用來驗證用戶輸入的一系列組件;您可以從“組件面板”的“驗證器”類別得到它們。最簡單的驗證將確保輸入字段具有某種類型的值。
雙精度范圍驗證器測試數值輸入的值是否在指定的范圍內。數據類型必須是浮點類型或可轉換為浮點的類型。其它驗證器包括長度驗證器和長型范圍驗證器。
使用長度驗證器來驗證為某個組件輸入的文本長度不短於或不長於您為驗證器的“minimum”和“maximum”屬性指定的值。該值必須是一個 java.lang.String。
使用長型范圍驗證器來驗證用戶輸入的值落入了一個最小和最大值的范圍內。該值必須是任何可轉換為 Java long 數據類型的字符串值。
圖 2:“組件面板”中的驗證器
當您使用驗證器(或在下面的使用轉換器中描述的轉換器)時,您也許還想使用一個消息組件來指明驗證失敗。Web 應用程序在調用任何值更改或動作偵聽器(如按鈕動作方法)前進行所有的驗證。如果發生一個或多個驗證錯誤,值更改偵聽器和動作偵聽器將不會被調用,而且 Web 應用程序重新渲染頁面以便讓用戶能改正問題。
對於本應用程序,您想檢查文本字段組件在頁面提交前包含至少一個字符。您還需要一個消息組件來指明驗證失敗。
您在前一節中添加的“消息”組件將在驗證失敗時向用戶指明。
展開“組件面板”的“驗證器”類別。從“組件面板”拖放一個“雙精度范圍驗證器”到文本字段組件上。
雙精度范圍驗證器是不可見組件。 將在“導航”窗口中出現缺省值“doubleRangeValidator1”,以及“屬性”窗口中的“validator”屬性,如下圖所示。
圖 3:“導航”窗口和“屬性”窗口
在“導航”窗口中,選中“doubleRangeValidator1”。
在“屬性”窗口中為驗證器設置范圍:
將“maximum”屬性設為“1000.0”(非常熱的溫度)。
將“minimum”屬性設為“-273.15”(例如攝氏溫標上的絕對零度)。
在本節中,您使應用程序能夠用雙精度范圍驗證器來驗證用戶輸入值。在下一節中,您將使用一個轉換器來使應用程序能夠計算一個攝氏溫度數值字符串輸入的華氏值。
使用轉換器
IDE 還提供了一系列轉換器,您可用來轉換組件數據。轉換器在您的組件屬性中的 java.lang.String 值和 Java 數據類型之間轉換數據類型。標准轉換器可從“組件面板”中的“轉換器”類別得到。當您綁定一個組件時,IDE 通常會為您使別數據類型,並在您建立值屬性綁定時設置適當的轉換器。但是,您也能從 IDE 中手動添加轉換器,方法是設置組件的轉換器屬性。
注意:轉換在驗證過程開始前進行。如果應用程序無法將用戶提供的值轉換為指定的數據類型,Web 應用程序就會拒絕輸入並發送錯誤消息。這個錯誤消息出現在“消息組”組件中,或在頁面上現有的相關聯的“消息”組件中。數值轉換器是很有用的轉換器,因為您可以用它來指定輸入必須匹配的樣式。
其它轉換器組件包括(但不限於)以下這些:
Big Decimal 轉換器在 java.lang.String 值和 java.math.BigDecimal 數據類型之間轉換,例如將 JSF 組件綁定到 Oracle 數據庫中 NUMBER 類型的列。
布爾轉換器組件在 java.lang.String 值和 java.lang.Boolean 數據類型或 Java boolean 原始類型之一之間轉換,例如將 JSF 組件綁定到數據庫中 BOOLEAN 類型的列。
字節轉換器組件在 java.lang.String 值和 java.lang.Byte 數據類型或 Java byte 原始類型之一之間轉換,例如將 JSF 組件綁定到數據庫中 SMALLINT 或 TINYINT 類型的列。
日歷轉換器組件在 java.lang.String 值和 java.math.util.Calendar 數據類型之間轉換。例如在您將 JSF 組件綁定到具有 dateTime 類型字段的 Web 服務時,該轉換器將起作用。
在前面的步驟中,您設置了一個驗證器來核實輸入的攝氏溫度落在絕對零度和 1000° 之間。在隨後的步驟中,您將使用一個雙精度轉換器來將用戶輸入轉換為雙精度型,這樣您就能用該雙精度型來計算攝氏輸入的華氏值。
展開“組件面板”的“轉換器”類別。從“組件面板”拖一個“雙精度轉換器”到“文本字段”組件上。
該轉換器指定文本字段組件返回 Double 對象而不是 String。缺省值“doubleConverter1”出現在“屬性”窗口和“導航”窗口中。
雙擊文本字段組件以在 Java 編輯器中打開它的源代碼。
添加下面的代碼(以粗體顯示)到 textField1_processValueChange 動作方法中。
代碼示例 1:值更改事件處理程序方法
public void textField1_processValueChange(ValueChangeEvent event) {
double celsiusTemp = ((Double) textField1.getText()).doubleValue();
double fahrenheitTemp = 9.0 * celsiusTemp / 5.0 + 32.0;
staticText1.setText(new Double(fahrenheitTemp));
}
這段代碼設了兩個變量:輸入 textField1 的值 celsiusTemp,以及通過對 celsiusTemp 應用指定的計算轉換出來的值 fahrenheitTemp。最後一行在靜態文本字段中設置了新值 fahrenheitTemp。
測試應用程序
在本節中,您將用各種輸入來運行應用程序,演示可能的驗證和轉換錯誤。
選擇“運行”>“運行主項目”來生成和運行應用程序。
從文本字段刪除 0.0,不輸入值按下 Enter。請核實對文本字段顯示了一個錯誤,如下圖所示。
圖 4:必需輸入時的驗證錯誤
錯誤實際上是因為我們將文本字段的“required”屬性設為“true”而發生的。當頁面訪客提交頁面時,Web 應用程序按下列順序進行輸入核實:
轉換
必需輸入
驗證
注意:值更改事件只在值實際上更改且所有的核實成功時發生。
輸入不同的數值來測試應用程序。下圖顯示了當您輸入 100 時的結果。
圖 5::成功驗證
請核實在您輸入超出范圍的值時顯示的驗證錯誤,以及在您輸入非數值字符串值時顯示的轉換錯誤。
下圖顯示當您輸入 -1000 時的結果。注意當驗證或轉換錯誤發生時,值更改偵聽器方法沒有被調用,靜態文本組件中的值沒有更改。
圖 6:值超出范圍時的驗證錯誤
輸入字母數字式的字符串,例如 20x。因為應用程序被配置為只轉換數值類型,它將返回轉換錯誤,如下圖所示。
圖 7:輸入值的格式不正確時的轉換錯誤
做更多:使用數值和日期時間轉換器
兩個標准轉換器——數值轉換器和日期時間轉換器——有它們自己的屬性,使您能夠指定數據的格式和類型。這個小教程演示如何使用這兩個轉換器。
下圖顯示了您將在本節中創建的頁面:
圖 8:貨幣轉換器應用程序
在“項目”窗口中,右鍵單擊“ValidatorConverter”>“Web 頁”,選擇“新建”>“Visual Web JSF”頁。將該頁命名為“Currency”,單擊完成。
右鍵單擊“ValidatorConverter”>“Web 頁”>“Currency.jsp”,選擇“設置為起始頁”。
從“組件面板”的“基本”類別,將一個“文本字段”組件拖放到頁面上。在“屬性”窗口中,將文本字段的“label”屬性設為“Dollar Amount:”,“required”屬性設為“True”。
將一個“按鈕”組件放到文本組件的右邊。將按鈕的文本更改為“Convert”。
重要提示:在 IE7 中,有一個已知的問題將影響 JSF 1.2 按鈕的寬度。解決辦法是將按鈕組件放到一個布局組件中(網格面板、組面板或布局面板)。改變布局組件的大小將自動改變按鈕組件的大小。
從“組件面板”的“基本”類別,將兩個“標簽”組件拖到頁面上。
將第一個標簽的文本設為“Converted to Euros:”,第二個標簽的文本設為“Date and Time:”。
分別將一個“靜態文本”組件放到各標簽旁。
從“組件”面板的“基本”類別,將一個“消息”組件拖放到 Date and Time 標簽下面。
按住 Ctrl+Shift 鍵,從消息組件向文本字段組件拖出一條線。
從“組件面板”的“轉換器”類別,將“數值轉換器”拖放到文本字段上。
數值轉換器指定文本字段組件返回一個 Number 對象而非 String。
在“數字格式”對話框中,從“類型”下拉列表中選擇“貨幣”。如下圖所示,將“小數位數”的“最大值”屬性設為“2”,“語言環境”設為“英文 (美國)”,單擊“確定”。
注意“貨幣代碼”是如何缺省為“USD 美利堅合眾國,美元”(和語言環境相關聯的貨幣縮寫、國家和貨幣名稱)的。請選擇不同的語言環境來顯示各種貨幣。
圖 9:“數字格式”對話框
數值轉換器出現在“屬性”窗口中的轉換器屬性和“導航”窗口中。
從“組件面板”拖放一個“數值轉換器”到 Converted to Euros 標簽旁的靜態文本上。
在“數字格式”對話框中,從“類型”下拉列表中選擇“貨幣”,從“語言環境”下拉列表中選擇“德文 (德國)”。將“小數數位”的“最大值”屬性設為 2,單擊“確定”。
這次“貨幣代碼”缺省為“EUR 歐盟成員國,歐元”。(如果,假如您選擇“德文 (瑞士)”,“貨幣代碼”將缺省為“CHF 瑞士,瑞士法朗”,因為瑞士不在歐盟地區中。)
從“組件面板”將一個“日期時間轉換器”拖放到 Date and Time 標簽旁的靜態文本上。
在“導航”窗口中,選中“dateTimeConverter1”。
在該轉換器對應的“屬性”窗口中,單擊“pattern”屬性對應的省略號按鈕。
在“模式”字段中鍵入“EEE, d MMM yyyy HH:mm:ss zzzz”,單擊“確定”。在您向模式添加元素時,當前值將出現在“屬性”窗口中的“pattern”屬性裡。
注意在您輸入元素時值是如何改變的。例如,如果您在開始鍵入“EEEE”而非“EEE”,模式就將包括完整的星期而非縮寫。如果您在末尾只輸入一個“z”,時區將會縮寫。
請參考 Java 教程中的定制格式課程以獲得格式化日期和時間的更多信息(外部鏈接將顯示在單獨的頁面中)。
添加代碼
雙擊 Convert 按鈕以在 Java 編輯器中打開它的源代碼。
緊靠 button1_action 方法上方添加下面兩行。0.74 近似於歐元到美元的匯率。
代碼示例 2:將美元轉換為歐元的常量
// 將美元轉換為歐元的常量
private static final double us2euros = 0.74;
將下面的代碼(粗體)添加到 button1_action 方法。代碼中的注釋表明每行的目的。
Code Sample 3: Constant Value for Dollars to Euros Exchange
public String button1_action( ) {
// 獲取用戶輸入的美元數量
Number dollars = (Number) textField1.getValue();
// 將美元轉換為歐元
double euros = dollars.doubleValue() * us2euros;
// 顯示歐元數量
staticText1.setText(new Double(euros));
// 算出日期和時間
Date date = new Date();
staticText2.setText(date);
return null;
}
右鍵單擊 Java 編輯器,選擇“修復導入”。選擇完整全限定名稱“java.util.Date”,單擊“確定”。
測試應用程序
運行應用程序。
輸入各種數量,例如“$10”。注意以下規則:
如果輸入字符串的第一個字符不是貨幣符號(這一次是 $),或在貨幣符號和第一個數字間有空格,轉換器將拋出異常。消息組件將顯示該錯誤。
您可以用逗號作為分隔符,例如 $1,234,但並不是必需的。即使逗號放在錯誤的位置,甚至在小數點右邊,都會被忽略。轉換後,逗號將重新顯示在正確位置。
在小數點後輸入超過兩位數字將造成四捨五入到最接近的便士。這是語言環境決定的,並且對不同的環境也不同,例如日本,貨幣值極少用數字值顯示。
下圖顯示了在您輸入“$100.00”時的結果。
圖 10:顯示轉換結果的頁面
下圖顯示當您輸入 100 而沒有 $ 時的結果。從前一次計算轉換的結果保留下來,但將顯示轉換錯誤。
圖 11:顯示轉換錯誤的頁面
要了解有關數字格式的更多信息,請查看 Java 教程定制格式(外部鏈接將顯示在單獨的頁面中)。
做更多:添加您自己的驗證處理程序
如果標准驗證器不能進行您需要的驗證檢查,您可以輕松添加自己的驗證處理程序。本節將使用 NetBeans Visual Web JSF 應用程序的功能來創建一個驗證處理程序,它能檢查用戶的輸入並將其限制為三位數。您可以將這些步驟添加到在前一節中創建的 Currency.jsp 頁面中。
單擊“設計”按鈕回到可視編輯器。
選擇 Dollar Amount 文本字段組件,將它的“required”屬性設為“False”。
從“組件”面板的“基本”類別,將一個“文本字段”組件拖放到頁面上。將文本字段的“label”屬性設為“Value:”,“required”屬性設為“True”。
將一個“按鈕”組件放到文本字段組件的右邊。將按鈕的文本更改為“Submit”。
將一個“消息”組件放到文本字段下方。按住 Ctrl+Shift 鍵,從消息組件向文本字段組件拖出一條線。
消息組件的文本變為“textField2 的概要消息”。
右鍵單擊文本字段組件,選擇“編輯事件處理程序”>“validate”。
這將打開 Java 編輯器。IDE 自動將 ValidatorException、FacesContext 和 FacesMessage 類的導入語句添加到代碼。插入點位於文本字段的 validate 事件上。第三個參數“value”是您將驗證的 String。
輸入下面的代碼(粗體)。
代碼示例 4:定制驗證器代碼
public void textField2_validate(FacesContext context, UIComponent component, Object value) {
String s = String.valueOf(value);
if (!s.matches("\\d\\d\\d")){
throw new ValidatorException(new FacesMessage("Not a three-digit number."));
}
}
String s 上的 matches 方法使用正則表達式來指定 String 可接受的合法值。\d 匹配數字(0-9)。
字符串字面中的“\”對 Java 解析器有特殊含義。您指定一個額外的“\”來轉義第二個“\”,確保它不被更改地通過解析器傳給模式解釋器。所以表達式 \d\d\d 匹配任何從 000 到 999 的三位數。
如果字符串不匹配該正則表達式,一個消息就被傳遞到 ValidatorException 構造方法。該消息被隊列到 FacesMessage 上,並在渲染響應過程中顯示到頁面上。
右鍵單擊 Java 編輯器,選擇“修復導入”。在“修復所有導入”對話框中,單擊“確定”。IDE 將導入 javax.faces.validator.ValidatorException 和 javax.faces.application.FacesMessage 包。
運行應用程序。輸入各種長度的數字和字符串來測試應用程序。還要在文本字段沒有輸入值時,核實顯示了標准驗證錯誤。
下圖顯示了當您輸入一個四位數時的結果。
圖 12:定制驗證器示例和結果
做更多:定制標准驗證器消息
標准驗證失敗時,您可以覆蓋 NetBeans IDE 提供的內建錯誤消息。您將為項目創建一個提供定制消息的資源包。注意這是全局覆蓋而非組件級覆蓋。這意味著需要它的所有組件都返回相同值。
定制消息
本節說明如何為 JSF 1.1 / J2EE 1.4 中的長型、雙精度范圍和長型范圍驗證器定制消息。正如你看到的,這將是比在 JSF 1.2 中添加定制消息稍長的過程。您使用 IDE 來為必需的輸入定制缺省錯誤消息。首先您創建一個資源包,程序用其中的鍵來映射向用戶顯示的字符串,然後您將編輯 faces-config.xml 來指向 MyResources.properties 資源包。
注意:本節中的步驟依賴於叫做 ValidatorConverter 的項目。如果您選擇不同的名稱,請調整所有項目名稱的使用來反映您的項目的名稱。
在“項目”窗口中,右鍵單擊“ValidatorsConverter”,選擇“新建”>“其他”。
在“新建文件”向導中,在“類別”字段中選擇“其他”,並在“文件類型”字段中選擇“屬性”文件,單擊“下一步”。
在“文件名稱”字段中輸入“MyResources”,在“文件夾”字段中輸入“src\java\validatorconverter”,單擊“完成”。
IDE 將創建資源包,並在 IDE 中打開 MyResources.properties 文件。MyResources.properties 文件為組件使用的消息提供替換文本。
關閉 MyResources.properties 文件。
在“文件”窗口中,展開“ValidatorConverter”>“src”>“java”>“validatorconverter”右鍵單擊 MyResources.properties,選擇“打開”以打開鍵-值屬性編輯器。
在鍵-值屬性編輯器中,您可以向資源包添加鍵-值對。
單擊“新建屬性”。
在“新建屬性”對話框中,在“鍵”字段中鍵入“javax.faces.component.UIInput.REQUIRED”。在“值”字段中鍵入“Please enter a value and then press Enter.”。
重要:請確保鍵的末尾沒有空格。空格將在運行時阻止程序運作。
要了解用於標准消息的所有鍵的列表,請查看下面的標准消息鍵。
單擊“確定”。值將顯示在“屬性”窗口中,如下圖所示。
圖 13:MyResources.properties 的屬性編輯器
在“項目”窗口中,展開“ValidatorConverter”>“Web 頁”>“WEB-INF”。右鍵單擊“faces-config.xml”,選擇“打開”。
In the editing toolbar, click XML. 在編輯工具欄中單擊“XML”。
在 faces-config.xml 文件中,輸入下面的代碼。注意這段代碼包含項目的名稱。如果您的項目名稱不是 ValidatorConverter,請適當更改代碼中的文本。注意在 message-bundle 元素中,您應當將項目名稱中的大寫字母改為小寫字母。
<application>
<message-bundle>webapplication6.MyResources</message-bundle>
</application>
message-bundle 元素代表本地化消息集。該元素包含到包含了本地化消息的資源包的全限定路徑,這一次是 validatorconverter.MyResources。
運行項目。
刪除文本字段中的任何文本,按下 Enter。
您的定制消息顯示在消息字段中,如下圖所示。
圖 14:定制錯誤消息
Standard Message Keys標准消息鍵
在 NetBeans IDE 中,您可以使用一個資源包來處理作為轉換、驗證,或請求處理生命周期過程中的其它應用程序動作的結果發生的信息消息。下表列出了用於標准消息的鍵。
鍵 描述 javax.faces.component.UIInput.CONVERSION 發生轉換錯誤 javax.faces.component.UIInput.REQUIRED 值是必需的 javax.faces.component.UISelectOne.INVALID 值不是有效選項 javax.faces.component.UISelectMany.INVALID 值不是有效選項 javax.faces.validator.NOT_IN_RANGE 指定的屬性不在預期的 {0} 和 {1} 之間 javax.faces.validator.DoubleRangeValidator.MAXIMUM 值大於允許的最大值 {0} javax.faces.validator.DoubleRangeValidator.MINIMUM 值小於允許的最小值 {0} javax.faces.validator.DoubleRangeValidator.TYPE 值的類型不正確 javax.faces.validator.LengthValidator.MAXIMUM 值大於允許的最大值 {0} javax.faces.validator.LengthValidator.MINIMUM 值小於允許的最小值 {0} javax.faces.validator.LongRangeValidator.MAXIMUM 值大於允許的最大值 {0} javax.faces.validator.LongRangeValidator.MINIMUM 值小於允許的最小值 {0} javax.faces.validator.LongRangeValidator.TYPE 值的類型不正確小結
在本教程中,您學習了如何:
使用轉換器來將字符串輸入轉換為數值,目的是用來在溫度格式間和貨幣值間轉換,以及顯示日期格式。
使用驗證器來確保輸入的值符合指定的范圍和格式。
創建您自己的驗證處理程序並定制向用戶顯示的消息。