欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
JSF 轉換與驗證 - 利用 JSF 的轉換和驗證框架來(lái)確保數據模型的完整性
雖然在 JSF Web 應用程序中使用轉換和驗證不一定要理解 JavaServer Faces 生命周期的基礎知識,但是在深入轉換和驗證內容之前,最好對一些基本知識做一回顧。此外,掌握一點(diǎn) JSF 生命周期技巧可以極大地幫助簡(jiǎn)化 Web 應用程序的開(kāi)發(fā)工作。還有助于更好地理解 JSF 的可插入能力。
圖 1 描繪了我們所說(shuō)的“基本 JSF 生命周期”。 基本 是在暗示這只是一個(gè)典型的處理所提交表單值的請求-響應(request-and-response)場(chǎng)景。
顯然,不同的場(chǎng)景對這里重點(diǎn)描述的生命周期有不同的影響。我們將在本文稍后介紹其中一些場(chǎng)景?,F在,只需要注意轉換和驗證過(guò)程發(fā)生在應用請求值、處理驗證 和呈現響應 階段即可。
我們將在稍后介紹為什么轉換和驗證會(huì )在這些階段出現,但是首先讓我們澄清一個(gè)更基本的問(wèn)題:轉換 是什么?簡(jiǎn)單地說(shuō),轉換是確保數據擁有正確的對象或者類(lèi)型的過(guò)程。下面是兩個(gè)典型的轉換:
字符串值可以轉換為 java.util.Date。 字符串值可以轉換為 Float。
至于驗證,它用于確保數據包含所期望的內容。下面是兩個(gè)典型的驗證:
java.util.Date 的格式為 MM/yyyy。 Float 在 1.0 和 100.0 之間。
轉換和驗證的主要目的是確保在更新模型數據之前已經(jīng)經(jīng)過(guò)了正確的無(wú)害處理。之后,當需要調用應用程序方法用這些些數據實(shí)際做一些事情 時(shí),就可以有把握地假定模型的某些狀態(tài)。轉換和驗證使您可以側重于業(yè)務(wù)邏輯,而不是側重于對輸入數據進(jìn)行繁瑣的資格認定,比如 null 檢驗、長(cháng)度限定、范圍邊界,等等。
因此,在更新模型數據 生命周期階段中,在組件數據被綁定到 backing bean 模型之前 進(jìn)行轉換和驗證處理是有道理的。正如圖 1 所示,轉換發(fā)生在應用請求值階段,而驗證發(fā)生在處理驗證階段。圖 2 突出顯示了這些階段。
注意,圖 2 中描繪的轉換和驗證過(guò)程表示了將 UIInput 組件的 immediate 屬性設置為 false 時(shí)的應用程序流程。如果這個(gè)屬性設置為 true,那么轉換和驗證會(huì )發(fā)生在生命周期更早的時(shí)期,即應用請求值階段(參見(jiàn)圖 3)。對使用 immediate 屬性的詳細討論超出了本文的范圍,但是在某些情況下,比如管理動(dòng)態(tài)清單(可能您還記得,本系列的上一篇文章中曾介紹過(guò)),它很有用,它甚至可以繞過(guò)驗證(在與 UICommand 組件結合使用時(shí))。能想像一個(gè)需要完全繞過(guò)驗證的應用程序嗎?
圖 3 展示了當 immediate 屬性設置為 true 時(shí),在 JSF 應用程序生命周期中的哪些地方進(jìn)行轉換和驗證。
下面,我們將用一個(gè)示例應用程序展示所討論的概念。本月的示例應用程序將展示 JSF 的轉換和驗證能力。記住,這個(gè)示例應用程序非常簡(jiǎn)單,沒(méi)有追求一些不必要的面面俱到:無(wú)論如何,我們的目的不是構建一個(gè)在真實(shí)世界中使用的應用程序!這個(gè)示例應用程序將展示以下幾點(diǎn):
使用標準 JSF 轉換器轉換表單字段數據。 使用標準 JSF 驗證組件驗證表單字段數據。 如何編寫(xiě)自定義轉換器和驗證器。 如何在 faces-config.xml 文件中注冊自定義轉換器和驗證器。 如何定制默認錯誤消息。
這個(gè)示例應用程序是一個(gè)簡(jiǎn)單的用戶(hù)注冊表單。我們的目標是收集用戶(hù)數據,比如姓名、年齡、電子郵箱地址和電話(huà)號碼。然后,我們將展示如何利用 JSF 轉換和驗證確保收集的數據對于模型是適合的。
這個(gè)應用程序使用了三個(gè) JSPi 頁(yè):
index.jsp 將用戶(hù)定向到 UserRegistration.jsp。 UserRegistration.jsp 包含應用程序的表單字段。 results.jsp 通知應用程序用戶(hù)已經(jīng)注冊。
我們將首先分析編寫(xiě) JSF 轉換過(guò)程的選擇。
如前所述,轉換是確保數據對象或者類(lèi)型正確的一個(gè)過(guò)程,因此,我們將字符串值轉換為其他類(lèi)型,比如 Date 對象、基本浮點(diǎn)型或者 Float 對象??梢允褂米詭У霓D換器,也可以編寫(xiě)自定義的轉換器。
JSF 提供了許多標準數據轉換器。也可以通過(guò)實(shí)現 Converter 接口插入自定義轉換器,但是這些將在后面進(jìn)行介紹。下表顯示了 JSF 進(jìn)行簡(jiǎn)單數據轉換所使用的轉換器 id 及其對應的實(shí)現類(lèi)。大多數數據轉換是自動(dòng)發(fā)生的。
javax.faces.BigDecimaljavax.faces.convert.BigDecimalConverter
javax.faces.BigIntegerjavax.faces.convert.BigIntegerConverter
javax.faces.Booleanjavax.faces.convert.BooleanConverter
javax.faces.Bytejavax.faces.convert.ByteConverter
javax.faces.Characterjavax.faces.convert.CharacterConverter
javax.faces.DateTimejavax.faces.convert.DateTimeConverter
javax.faces.Doublejavax.faces.convert.DoubleConverter
javax.faces.Floatjavax.faces.convert.FloatConverter
圖 4 展示了用戶(hù)年齡的默認轉換。JSF 標簽配置如下:
<!-- UserRegistration.jsp -->
<h:inputText id="age" value="#{UserRegistration.user.age}"/>
UserRegistration.user.age 表示一個(gè)值綁定屬性,它的類(lèi)型為 int。對于基本型或者 BigInteger/ BigDecimal 的綁定,JSF 選擇了標準轉換器。不過(guò),還可以通過(guò) <f:converter/> 標簽,利用一個(gè)特定的轉換器來(lái)增加粒度,如下所示。
<!-- UserRegistration.jsp -->
<h:inputText id="age" value="#{UserRegistration.user.age}">
<f:converter id="javax.faces.Short"/>
</h:inputText>
在圖 5 中,可以看到 JSF 使用標準轉換器的場(chǎng)景。在這種情況下,雖然年齡實(shí)際上是一個(gè)有效的整數,但轉換仍然會(huì )失敗,因為該值不是短整型的。
盡管在默認情況下,JSF 可以很好地處理基本型及類(lèi)似的類(lèi)型,但是在處理日期數據時(shí),必須指定轉換標簽 <f:convertDateTime/>。這個(gè)標簽基于 java.text 包,并使用短、長(cháng)和自定義樣式。下面是一個(gè)例子:
<!-- UserRegistration.jsp -->
<h:inputText id="birthDate" value="#{UserRegistration.user.birthDate}">
<f:convertDateTime pattern="MM/yyyy"/>
</h:inputText>
這個(gè)例子展示了如何用 <f:convertDateTime/> 確保用戶(hù)的生日可以轉換為格式為 MM/yyyy(月/年)的日期對象。請參閱 JSF 的 java.text.SimpleDataFormat (在參考資料 中),以獲取模式列表。
除了可以轉換日期和時(shí)間格式外,JSF 還提供了處理像百分數或者貨幣數據這類(lèi)值的特殊轉換器。這個(gè)轉換器處理分組(如逗號)、小數、貨幣符號等。例如,以下 <f:convertNumber/> 的用法就是處理貨幣的一種技巧:
<!-- UserRegistration.jsp -->
<h:inputText id="salary" value="#{UserRegistration.user.salary}">
<f:convertNumber maxFractionDigits="2"
groupingUsed="true"
currencySymbol="$"
maxIntegerDigits="7"
type="currency"/>
</h:inputText>
在圖 6 中,可以看到一些格式編排不正確的貨幣數據,以及所導致的轉換錯誤。
如果需要將字段數據轉換為特定于應用程序的值對象,則需要自定義數據轉換,如下面例子所示:
String 轉換為 PhoneNumber 對象 (PhoneNumber.areaCode、PhoneNumber.prefix、 ...)。 String 轉換為 Name 對象 (Name.first、Name.last)。 String 轉換為 ProductCode 對象 (ProductCode.partNum、ProductCode.rev、 ...)。
要創(chuàng )建自定義轉換器,必須完成以步驟:
實(shí)現 Converter 接口(也就是 javax.faxes.convert.Converter)。 實(shí)現 getAsObject 方法,它將一個(gè)字段(字符串)轉換為一個(gè)對象(例如,PhoneNumber)。 實(shí)現 getAsString 方法,它將一個(gè)對象(如 PhoneNumber)轉換為一個(gè)字符串。 在 Faces 上下文中注冊自定義轉換器。 用 <f:converter/> 標簽在 JSP 中插入這個(gè)轉換器。
您可以自己看到如何在 JSF 應用程序生命周期中加入這些步驟。在圖 7 中,JSF 在應用請求值階段調用自定義轉換器的 getAsObject 方法。轉換器必須在這里將請求字符串轉換為所需的對象類(lèi)型,然后返回這個(gè)對象,將它存儲在相應的 JSF 組件中。如果該值被返回呈現在視圖中,那么 JSF 將在呈現響應階段調用 getAsString 方法。這意味著(zhù)轉換器還要負責將對象數據轉換回字符串表示形式。
我們將使用一個(gè)案例分析來(lái)展示 Converter 接口、getAsObject 和 getAsString 方法的實(shí)現,同時(shí)還將展示如何在 Faces 上下文中注冊這個(gè)轉換器。
這個(gè)案例分析的目的是將一個(gè)單字段字符串值轉換為一個(gè) PhoneNumber 對象。我們將一步一步地完成這個(gè)轉換過(guò)程。
這一步實(shí)現 Converter 接口。
import javax.faces.convert.Converter;
import org.apache.commons.lang.StringUtils;
...
public class PhoneConverter implements Converter {
...
}
這一步將一個(gè)字段值轉換為一個(gè) PhoneNumber 對象。
public class PhoneConverter implements Converter {
...
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (StringUtils.isEmpty(value)){ return null;}
PhoneNumber phone = new PhoneNumber();
String [] phoneComps = StringUtils.split(value," ,()-");
String countryCode = phoneComps[0];
phone.setCountryCode(countryCode);
if ("1".equals(countryCode)){
String areaCode = phoneComps[1];
String prefix = phoneComps[2];
String number = phoneComps[3];
phone.setAreaCode(areaCode);
phone.setPrefix(prefix);
phone.setNumber(number);
}else {
phone.setNumber(value);
}
return phone;
}
}
這一步將一個(gè) PhoneNumber 對象轉換為一個(gè)字符串。
public class PhoneConverter implements Converter {
...
public String getAsString(FacesContext context,
UIComponent component, Object value) {
return value.toString();
}
}
public class PhoneNumber implements Serializable {
...
public String toString(){
if (countryCode.equals("1")){
return countryCode + " " + areaCode
+ " " + prefix + " " + number;
}else{
return number;
}
}
}
第 4 步可以以?xún)煞N方式執行。第一種選擇使用(比如)arcmind.PhoneConverter 的 id 來(lái)注冊 PhoneConverter 類(lèi)。JSP 頁(yè)中的 <f:converter/> 標簽會(huì )使用這個(gè) id。下面是第 4 步的選項 1 的代碼:
<converter>
<converter-id>arcmind.PhoneConverter</converter-id>
<converter-class>com.arcmind.converters.PhoneConverter</converter-class>
</converter>
另一種方法是注冊 PhoneConverter 類(lèi)來(lái)自動(dòng)處理所有 PhoneNumber 對象,如下所示。
<converter>
<converter-for-class>com.arcmind.value.PhoneNumber</converter-for-class>
<converter-class>com.arcmind.converters.PhoneConverter</converter-class>
</converter>
自然,下一步的執行取決于所選的注冊方法。如果選擇使用 arcmind.PhoneConverter 的 id 來(lái)注冊 PhoneConverter 類(lèi),那么就使用 <f:converter/> 標簽,如下所示。
<h:inputText id="phone" value="#{UserRegistration.user.phone}">
<f:converter converterId="arcmind.PhoneConverter" />
</h:inputText>
如果選擇注冊 PhoneConverter 類(lèi)來(lái)自動(dòng) 處理所有 PhoneNumber,那么就不需要在 JSP 頁(yè)中使用 <f:converter/> 標簽。下面是第 5 步的不帶轉換器標簽的代碼。
<h:inputText id="phone" value="#{UserRegistration.user.phone}">
[Look mom no converter!]
</h:inputText>
這樣,我們已經(jīng)完成了這個(gè)示例應用程序的轉換處理代碼!到目前為止完成的應用程序如下所示。
如前所述,JSF 驗證可以確保應用程序數據包含預期的內容,例如:
java.util.Date 為 MM/yyyy 格式。 Float 在 1.0 和 100.0 之間。
在 JSF 中有 4 種驗證:
自帶驗證組件。 應用程序級驗證。 自定義驗證組件(它實(shí)現了 Validator 接口)。 在 backing bean 中的驗證方法(內聯(lián))。
我們將在下面的討論中介紹并展示每一種形式。
圖 9 顯示了用戶(hù)注冊表單中名字字段的生命周期案例分析。代碼引用被有意解釋為偽代碼(pseudo-code)。
下面是 JSF 提供的一組標準驗證組件:
DoubleRangeValidator:組件的本地值必須為數字類(lèi)型,必須在由最小和/或最大值所指定的范圍內。 LongRangeValidator:組件的本地值必須為數字類(lèi)型,并且可以轉換為長(cháng)整型,必須在由最小和/或最大值所指定的范圍內。 LengthValidator:類(lèi)型必須為字符串,長(cháng)度必須在由最小和/或最大值所指定的范圍內。
在我們的示例應用程序中,用戶(hù)的年齡可以是任意有效的整數(byte、short、int)。因為將年齡設置為(比如說(shuō))-2 是無(wú)意義的,所以可能要對這個(gè)字段添加一些驗證。下面是一些簡(jiǎn)單的驗證代碼,用以確保年齡字段中的數據模型完整性:
<h:inputText id="age" value="#{UserRegistration.user.age}">
<f:validateLongRange maximum="150"
minimum="0"/>
</h:inputText>
完成年齡字段后,可能希望指定對名字字段的長(cháng)度加以限制??梢韵襁@樣編寫(xiě)這個(gè)驗證:
<h:inputText id="firstName"
value="#{UserRegistration.user.firstName}">
<f:validateLength minimum="2"
maximum="25" />
</h:inputText>
圖 10 顯示了由上面標準驗證示例所生成的默認詳細驗證消息。
盡管 JSF 自帶的驗證在許多情況下都可以滿(mǎn)足,但是它有一些局限性。在處理電子郵件驗證、電話(huà)號碼、URL、日期等數據時(shí),有時(shí)編寫(xiě)自己的驗證器會(huì )更好一些,不過(guò)我們將在稍后對此進(jìn)行討論。
在概念上,應用程序級驗證實(shí)際上是業(yè)務(wù)邏輯驗證。JSF 將表單和/或字段級驗證與業(yè)務(wù)邏輯驗證分離開(kāi)。應用程序級驗證主要需要在 backing bean 中添加代碼,用這個(gè)模型確定綁定到模型中的數據是否合格。對于購物車(chē),表單級驗證可以驗證輸入的數量是否有效,但是需要使用業(yè)務(wù)邏輯驗證檢查用戶(hù)是否超出了他或者她的信用額度。這是在 JSF 中分離關(guān)注點(diǎn)的另一個(gè)例子。
例如,假定用戶(hù)單擊了綁定到某個(gè)操作方法的按鈕,那么就會(huì )在調用應用程序階段調用這個(gè)方法(有關(guān)的細節,請參見(jiàn)上面的圖 1)。假定在更新模型階段進(jìn)行了更新,那么在對模型數據執行任何操縱之前,可以添加一些驗證代碼,根據應用程序的業(yè)務(wù)規則檢查輸入的數據是否有效。
例如,在這個(gè)示例應用程序中,用戶(hù)單擊了 Register 按鈕,這個(gè)按鈕被綁定到應用程序控制器的 register() 方法。我們可以在 register() 方法中添加驗證代碼,以確定名字字段是否為 null。如果該字段為 null,那么還可以在 FacesContext 中添加一條消息,指示相關(guān)組件返回到當前頁(yè)。
其實(shí)它現在并不是業(yè)務(wù)規則邏輯的一個(gè)好例子。更好的例子是檢查用戶(hù)是否超出了她或者她的信用額度。在該例中,不是檢查字段是否為空,我們可以調用模型對象的方法來(lái)確保當前用戶(hù)已經(jīng)不在系統中。
圖 11 描繪了這個(gè)過(guò)程。
注意在 register() 方法中,消息是如何以 ${formId}:${fieldId} 的形式添加到 FacesContext 中的。圖 12 顯示了消息與組件 id 之間的關(guān)系。
應用級驗證非常直觀(guān)并且容易實(shí)現。不過(guò),這種形式的驗證是在其他形式的驗證(標準、自定義、組件)之后發(fā)生的。
應用程序級驗證的優(yōu)點(diǎn)如下:
容易實(shí)現。 不需要單獨的類(lèi)(自定義驗證器)。 不需要頁(yè)編寫(xiě)者指定驗證器。
應用程序級驗證的缺點(diǎn)如下:
在其他形式的驗證(標準、自定義)之后發(fā)生。 驗證邏輯局限于 backing bean 方法,使得重用性很有限。 在大型應用程序和/或團隊環(huán)境中可能難于管理。
最終,應用程序級驗證只應該用于那些需要業(yè)務(wù)邏輯驗證的環(huán)境中。
對于標準 JSF 驗證器不支持的數據類(lèi)型,則需要建立自己的自定義驗證組件,其中包括電子郵件地址和郵政編碼。如果需要明確控制顯示給最終用戶(hù)的消息,那么還需要建立自己的驗證器。在 JSF 中,可以創(chuàng )建可在整個(gè) Web 應用程序中重復使用的可插入驗證組件。
創(chuàng )建自定義驗證器的步驟如下,我們將一步步地分析:
創(chuàng )建一個(gè)實(shí)現了 Validator 接口的類(lèi) (javax.faces.validator.Validator)。 實(shí)現 validate 方法。 在 faces-confix.xml 文件中注冊自定義驗證。 在 JSP 頁(yè)中使用 <f:validator/> 標簽。
下面是創(chuàng )建自定義驗證器的分步示例代碼。
第一步是實(shí)現 Validator 接口。
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
...
public class ZipCodeValidator implements Validator{
private boolean plus4Required;
private boolean plus4Optional;
/** Accepts zip codes like 85710 */
private static final String ZIP_REGEX = "[0-9]{5}";
/** Accepts zip code plus 4 extensions like "-1119" or " 1119" */
private static final String PLUS4_REQUIRED_REGEX = "[ |-]{1}[0-9]{4}";
/** Optionally accepts a plus 4 */
private static final String PLUS4_OPTIONAL_REGEX = "([ |-]{1}[0-9]{4})?";
...
}
接下來(lái),需要實(shí)現 validate 方法。
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
/* Create the correct mask */
Pattern mask = null;
/* more on this method later */
initProps(component);
if (plus4Required){
mask = Pattern.compile(ZIP_REGEX + PLUS4_REQUIRED_REGEX);
} else if (plus4Optional){
mask = Pattern.compile(ZIP_REGEX + PLUS4_OPTIONAL_REGEX);
} else if (plus4Required && plus4Optional){
throw new IllegalStateException("Plus 4 is either optional or required");
}
else {
mask = Pattern.compile(ZIP_REGEX);
}
/* Get the string value of the current field */
String zipField = (String)value;
/* Check to see if the value is a zip code */
Matcher matcher = mask.matcher(zipField);
if (!matcher.matches()){
FacesMessage message = new FacesMessage();
message.setDetail("Zip code not valid");
message.setSummary("Zip code not valid");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
您現在應該熟悉在 FacesContext 中注冊自定義驗證器的代碼了。
<validator>
<validator-id>arcmind.zipCodeValidator</validator-id>
<validator-class>com.arcmind.jsfquickstart.validation.ZipCodeValidator</validator-class>
</validator>
<f:validator/> 標簽聲明使用 zipCodeValidator。<f:attribute/> 標簽將 plus4Optional 屬性設置為 true。注意,它定義了 inputText 組件的屬性,而不是 驗證器的屬性!
<h:inputText id="zipCode" value="#{UserRegistration.user.zipCode}">
<f:validator validatorId="armind.zipCodeValidator"/>
<f:attribute name="plus4Optional" value="true"/>
</h:inputText>
為了讀取 zipCodeinputText 組件的 plus4Optional 屬性,請完成以下步驟::
private void initProps(UIComponent component) {
Boolean optional = Boolean.valueOf((String) component.getAttributes().
get("plus4Optional"));
Boolean required = Boolean.valueOf((String) component.getAttributes().
get("plus4Required"));
plus4Optional = optional==null ? plus4Optional :
optional.booleanValue();
plus4Required = required==null ? plus4Optional :
required.booleanValue();
}
總體而言,創(chuàng )建自定義驗證器是相當直觀(guān)的,并且可以使該驗證在許多應用程序中重復使用。缺點(diǎn)是必須創(chuàng )建一個(gè)類(lèi),并在 faces 上下文中管理驗證器注冊。不過(guò),通過(guò)創(chuàng )建一個(gè)使用這個(gè)驗證器的自定義標簽,使其看上去像是一個(gè)自帶的驗證,可以進(jìn)一步實(shí)現自定義驗證器。對于常見(jiàn)的驗證問(wèn)題,如電子郵件驗證,這種方法可以支持這樣一種設計理念,即代碼重用和一致的應用程序行為是最重要的。
作為創(chuàng )建單獨的驗證器類(lèi)的替代方法,可以只在 backing bean 的方法中實(shí)現自定義驗證,只要這個(gè)方法符合 Validator 接口的 validate 方法的參數簽名即可。例如,可以編寫(xiě)以下方法:
[SomeBackingBean.java]
public void validateEmail(FacesContext context,
UIComponent toValidate,
Object value) {
String email = (String) value;
if (email.indexOf(‘@‘) == -1) {
((UIInput)toValidate).setValid(false);
FacesMessage message = new FacesMessage("Invalid Email");
context.addMessage(toValidate.getClientId(context), message);
}
}
之后,可通過(guò)如下所示的 validator 屬性在 JSF 中使用這個(gè)方法:
<h:inputText id="email"
value="#{UserRegistration.user.email}"
validator="#{UserRegistration.validateEmail}"
required="true">
</h:inputText>
JSF 用 validateEmail 方法對綁定到 user.email 模型屬性的 inputText 組件值進(jìn)行自定義驗證。如果電子郵件格式無(wú)效,那么就在相關(guān)組件的 faces 上下文中添加消息??紤]到這種驗證方法實(shí)際上是 backing bean 的一部分,為什么通常必須用某個(gè)值與相關(guān)組件的關(guān)聯(lián)來(lái)評估該值,而不是直接檢查本地 bean 屬性呢?線(xiàn)索就在前面的生命周期圖中。如果現在不能馬上找到答案,也不要擔心,我們將在本文的最后對此加以說(shuō)明。
注意上面 email 標簽的 required 屬性。利用 required 屬性是一種默認 驗證形式。如果這個(gè)屬性是 true,那么相應的組件必須有一個(gè)值。一個(gè)重要的說(shuō)明:如果 required 屬性為 false,那么就不用對這個(gè)標簽/組件指派驗證,這樣,JSF 將跳過(guò)對這個(gè)組件的驗證,并讓值和組件的狀態(tài)保持不變。
圖 13 概述了我們討論過(guò)的驗證形式。
您可能注意到了,JSF 提供的默認轉換和驗證消息非常長(cháng),這會(huì )讓那些總是輸入無(wú)效表單數據的最終用戶(hù)感到困惑和惱火。幸運的是,您可以通過(guò)創(chuàng )建自己的消息資源綁定來(lái)改變 JSF 提供的默認消息。jsf-impl.jar (或類(lèi)似的文件中)中包含了一個(gè) message.properties 文件,該文件包含圖 14 所示的默認消息。
通過(guò)創(chuàng )建自己的 message.properties 文件并斷開(kāi)指定場(chǎng)所的 faces 上下文中綁定的消息資源,您可以更改默認消息,如圖 15 所示。
關(guān)于在 JSF 中創(chuàng )建自定義轉換和驗證消息的更多內容請參前閱參考資料。
我們在本文前面留下了一些問(wèn)題讓您考慮,現在可以解決它們了!我們提到的一件事是對 UICommand 按鈕使用immediate 屬性,比如 commandLink 或者 commandButtons?,F在請您考慮希望在什么樣的場(chǎng)景中跳過(guò)驗證。
基本上只要用戶(hù)需要輸入數據,就需要對這個(gè)數據進(jìn)行驗證。不過(guò),如果整個(gè)數據項是可選的,那么就不需要進(jìn)行驗證。一種避免 JSF 生命周期的驗證階段的方法是利用 UICommand 組件的 immediate 屬性,該屬性可以在處理驗證階段之前 的應用請求值階段期間(而不是在處理驗證階段 之后 的調用應用程序階段)強制調用這個(gè)操作。
immediate 屬性允許您通過(guò)標準瀏覽規則控制頁(yè)流程,并繞過(guò)驗證??梢葬槍μ囟ǖ膱?chǎng)景實(shí)現這項技術(shù),比如帶有可選步驟和/或表單的在線(xiàn)向導(如當用戶(hù)單擊 Skip 按鈕以進(jìn)入下一視圖),或者在用戶(hù)因為某種原因而取消某個(gè)表單的情況下。
我們在本文中留下的第二個(gè)問(wèn)題是:既然驗證方法實(shí)際上是 backing bean 的一部分,那么為什么通常必須利用組件關(guān)聯(lián)來(lái)判斷它的值。請參閱前面的JSF 應用程序生命周期,看看您能否找到答案。
這里的密訣是:盡管 validateEmail 嵌入驗證方法是實(shí)際的 backing bean 的一部分,但是該方法必須通過(guò)組件關(guān)聯(lián)來(lái)引用這,而不是直接訪(fǎng)問(wèn)本地屬性來(lái)引用值。由于驗證發(fā)生在組件值綁定到模型之前(在更新模型值階段),所以模型處于未知狀態(tài)。因此,必須編寫(xiě)嵌入自定義驗證邏輯,就像使用一個(gè)自定義 Validator 對象處理驗證一樣。這也解釋了維護相同方法簽名的需求。
這些尚待解決的枝節問(wèn)題有什么意義呢,當然,它們最終將我們帶回 JSF 應用程序生命周期。將這些問(wèn)題匯總在一起,就能體現充分理解生命周期的重要性 —— 向后、向前或由內向外,這樣您就可以在需要的時(shí)候操縱它。
在本文中我們討論了相當多的 JSF 轉換和驗證的基本內容。事實(shí)上,我們討論了在自己的應用程序中使用這些過(guò)程需要知道的大部分內容(至少對這個(gè)版本的 JSF 而言)!
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
JSF 轉換與驗證
ASP.NET Web 配置指南
使用 JavaServer Faces 構建 Apache Geronimo 應用程序,第 4 部分: 使用 Apache Trinidad 組件擴展 JSF
十一、 自訂轉換器
JSF學(xué)習筆記
Struts ActionForm中自定義轉換器Converter(簡(jiǎn)單易懂)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久