使用Bean验证扩展PrimeFaces CSV
你們中有些人已經(jīng)知道我和我的合著者M(jìn)ert?al??kan正在研究PrimeFaces Cookbook的2.版。 Packt Publishing允許我從新章節(jié)“客戶(hù)端驗(yàn)證”的一個(gè)食譜中摘錄一小部分摘錄。 這將有助于使讀者知道這本書(shū)的內(nèi)容。 在此博客文章中,我想討論使用Bean驗(yàn)證擴(kuò)展的PrimeFaces客戶(hù)端驗(yàn)證(CSV)。
Bean Validation是一個(gè)驗(yàn)證模型,可作為Java EE 6平臺(tái)的一部分使用,它允許通過(guò)約束將字段,方法或類(lèi)上的批注形式的驗(yàn)證。 JSF 2.2支持對(duì)托管bean以及Spring或CDI bean中的字段(屬性及其getter / setter)的驗(yàn)證。 只要不使用OmniFaces之類(lèi)的實(shí)用程序,尚不支持在類(lèi)級(jí)別進(jìn)行驗(yàn)證。
PrimeFaces的CSV具有與Bean驗(yàn)證的內(nèi)置集成。 注釋定義的約束可以通過(guò)CSV框架在客戶(hù)端進(jìn)行驗(yàn)證。 盡管Bean Validation API定義了一整套標(biāo)準(zhǔn)約束注釋,但可以輕松想到這些標(biāo)準(zhǔn)注釋不足的情況。 對(duì)于這些情況,您可以為特定的驗(yàn)證要求創(chuàng)建自定義約束。 PrimeFaces中的客戶(hù)端驗(yàn)證API與自定義約束無(wú)縫協(xié)作。
在本食譜中,我們將開(kāi)發(fā)一種特殊的自定義約束和驗(yàn)證器,以驗(yàn)證卡驗(yàn)證碼( CVC )。 CVC用作帶有銀行卡號(hào)的安全功能。 它是一個(gè)長(zhǎng)度在三到四位數(shù)之間的數(shù)字。 例如,萬(wàn)事達(dá)卡或維薩卡要求輸入三位數(shù),而美國(guó)運(yùn)通卡要求輸入四位數(shù)。 因此,CVC驗(yàn)證將取決于所選的銀行卡。 用戶(hù)可以通過(guò)p:selectOneMenu選擇銀行卡,然后在p:inputText中輸入CVC,然后提交輸入。
怎么做…
我們將從用于CVC字段的自定義注釋開(kāi)始。
import org.primefaces.validate.bean.ClientConstraint; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD;@Constraint(validatedBy = CvcConstraintValidator.class) @ClientConstraint(resolvedBy = CvcClientConstraint.class) @Target({FIELD, METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidCVC {String message() default "{invalid.cvc.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};// identifier of the select menu with cardsString forCardMenu() default ""; }@Constraint是Bean驗(yàn)證API的常規(guī)注解,而@ClientConstraint是PrimeFaces CSV框架的注解,它有助于解析元數(shù)據(jù)。 開(kāi)發(fā)的注釋定義消息密鑰invalid.cvc.message并且具有Custom屬性forCardMenu 。 此屬性的值是任何有關(guān)PrimeFaces Selectors (PFS)搜索表達(dá)式,用于引用銀行卡的選擇菜單。 這是必需的,因?yàn)橛行У腃VC值取決于所選的卡。
CvcConstraintValidator的目標(biāo)是驗(yàn)證輸入長(zhǎng)度。
public class CvcConstraintValidator implements ConstraintValidator<ValidCVC, Integer> {@Overridepublic void initialize(ValidCVC validCVC) {}@Overridepublic boolean isValid(Integer cvc, ConstraintValidatorContext context) {if (cvc == null || cvc < 0) {return false;}int length = (int) (Math.log10(cvc) + 1);return (length >= 3 && length <= 4);} }CvcClientConstraint的目標(biāo)是準(zhǔn)備元數(shù)據(jù)。
public class CvcClientConstraint implements ClientValidationConstraint {private static final String CARDMENU_METADATA = "data-forcardmenu";@Overridepublic Map<String, Object> getMetadata(ConstraintDescriptor constraintDescriptor) {Map<String, Object> metadata = new HashMap<String, Object>();Map attrs = constraintDescriptor.getAttributes();String forCardMenu = (String) attrs.get("forCardMenu");if (StringUtils.isNotBlank(forCardMenu)) {metadata.put(CARDMENU_METADATA, forCardMenu);}return metadata;}@Overridepublic String getValidatorId() {return ValidCVC.class.getSimpleName();} }讓我們轉(zhuǎn)到客戶(hù)端實(shí)現(xiàn)。 首先,我們必須創(chuàng)建一個(gè)JavaScript文件,說(shuō)validators.js ,并命名空間中的注冊(cè)有自己的驗(yàn)證PrimeFaces.validator名為ValidCVC 。 此名稱(chēng)是由getValidatorId()方法返回的唯一ID(請(qǐng)參閱類(lèi)CvcClientConstraint )。 要實(shí)現(xiàn)的功能稱(chēng)為validate() 。 它有兩個(gè)參數(shù):元素本身和要驗(yàn)證的當(dāng)前輸入值。
PrimeFaces.validator['ValidCVC'] = {MESSAGE_ID: 'invalid.cvc',validate: function (element, value) {// find out selected menu valuevar forCardMenu = element.data('forcardmenu');var selOption = forCardMenu ?PrimeFaces.expressions.SearchExpressionFacade.resolveComponentsAsSelector(forCardMenu).find("select").val() : null;var valid = false;if (selOption && selOption === 'MCD') {// MasterCardvalid = value > 0 && value.toString().length == 3;} else if (selOption && selOption === 'AMEX') {// American Expressvalid = value > 0 && value.toString().length == 4;}if (!valid) {throw PrimeFaces.util.ValidationContext.getMessage(this.MESSAGE_ID);}} };其次,我們必須為本地化消息創(chuàng)建一個(gè)JavaScript文件,例如lang_en.js 。
PrimeFaces.locales['en'] = {messages : PrimeFaces.locales['en_US'].messages };$.extend(PrimeFaces.locales['en'].messages, {...'invalid.cvc':'Card Validation Code is invalid' });Bean具有兩個(gè)必需屬性,并用@NotNull注釋。 另外,屬性cvc帶有我們的自定義注釋@ValidCVC 。 forCardMenu的屬性forCardMenu指向列出可用銀行卡的p:selectOneMenu的樣式類(lèi)。
@Named @ViewScoped public class ExtendCsvBean implements Serializable {@NotNullprivate String card;@NotNull@ValidCVC(forCardMenu = "@(.card)")private Integer cvc;public void save() {RequestContext.getCurrentInstance().execute("alert('Saved!')");}// getters / setters... }在XHTML片段中,我們有一個(gè)帶有兩個(gè)銀行卡的選擇菜單和一個(gè)CVC輸入字段。 p:commandButton驗(yàn)證字段并在回發(fā)時(shí)執(zhí)行方法save() 。
<h:panelGrid id="pgrid" columns="3" cellpadding="3" style="margin-bottom:10px;"><p:outputLabel for="card" value="Card"/><p:selectOneMenu id="card" styleClass="card"value="#{extendCsvBean.card}"><f:selectItem itemLabel="Please select a card"itemValue="#{null}"/><f:selectItem itemLabel="MasterCard"itemValue="MCD"/><f:selectItem itemLabel="American Express"itemValue="AMEX"/></p:selectOneMenu><p:message for="card"/><p:outputLabel for="cvc" value="CVC"/><p:inputText id="cvc" value="#{extendCsvBean.cvc}"/><p:message for="cvc"/> </h:panelGrid><p:commandButton validateClient="true" value="Save"process="@this pgrid" update="pgrid" action="#{extendCsvBean.save}"/>注意:如您所見(jiàn), p:selectOneMenu和p:inputText指定必需的屬性。 我們可以實(shí)現(xiàn)的轉(zhuǎn)變@NotNull注釋與價(jià)值所需要的屬性, true ,如果我們?cè)O(shè)置的參數(shù)范圍內(nèi)primefaces.TRANSFORM_METADATA至true 。
在最后一步中,所有必需JavaScript文件都必須包含在頁(yè)面上。
<h:outputScript library="js" name="chapter10/lang_en.js"/> <h:outputScript library="js" name="chapter10/validators.js"/>下兩張圖片顯示驗(yàn)證失敗時(shí)會(huì)發(fā)生什么
如果一切正常,則出現(xiàn)一個(gè)帶有已保存文本的警告框。 向用戶(hù)顯示。
怎么運(yùn)行的…
消息密鑰invalid.cvc.message和文本應(yīng)放在名為ValidationMessages資源包中,例如ValidationMessages_en.properties 。 ValidationMessages是Bean驗(yàn)證規(guī)范中指定的標(biāo)準(zhǔn)名稱(chēng)。 屬性文件應(yīng)位于應(yīng)用程序類(lèi)路徑中,并包含以下條目: invalid.cvc.message=Card Validation Code is invalid 。 此配置對(duì)于服務(wù)器端驗(yàn)證很重要。
類(lèi)CvcClientConstraint中的getMetadata()方法提供了一個(gè)具有名稱(chēng),值對(duì)的映射。 元數(shù)據(jù)在呈現(xiàn)HTML中公開(kāi)。 可以通過(guò)element.data(name)在客戶(hù)端訪(fǎng)問(wèn)這些值,其中element是基礎(chǔ)本機(jī)HTML元素的jQuery對(duì)象。 具有元數(shù)據(jù)的CVC字段呈現(xiàn)為
<input type="text" data-forcardmenu="@(.card)"data-p-con="javax.faces.Integer" data-p-required="true"...>最有趣的部分是客戶(hù)端驗(yàn)證器的實(shí)現(xiàn)。 要驗(yàn)證的值已經(jīng)是數(shù)字,因?yàn)槭紫人蒔rimeFaces的內(nèi)置客戶(hù)端轉(zhuǎn)換器針對(duì)數(shù)據(jù)類(lèi)型java.lang.Integer轉(zhuǎn)換。 我們只需要檢查該值是否為正且具有有效長(zhǎng)度。 有效長(zhǎng)度取決于菜單p:selectOneMenu中所選的卡片,PrimeFaces JavaScript API可以使用PrimeFaces.expressions.SearchExpressionFacade.resolveComponentsAsSelector(selector)對(duì)其進(jìn)行訪(fǎng)問(wèn),其中選擇器是任何PrimeFaces選擇器,在我們的示例中為@(.card) 。 如果驗(yàn)證失敗,則通過(guò)引發(fā)throw PrimeFaces.util.ValidationContext.getMessage(text, parameter)引發(fā)異常。
通過(guò)在p:commandButton上設(shè)置validateClient=”true”來(lái)觸發(fā)客戶(hù)端驗(yàn)證。
翻譯自: https://www.javacodegeeks.com/2015/01/extending-primefaces-csv-with-bean-validation.html
總結(jié)
以上是生活随笔為你收集整理的使用Bean验证扩展PrimeFaces CSV的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 酷安安卓市场(安卓酷市场)
- 下一篇: 合肥市房产局官网备案价查询(合肥市房产局