使用Bean验证扩展PrimeFaces CSV

你们中有些人已经知道我和我的合著者MertÇalışkan正在研究PrimeFaces Cookbook的2.版。 Packt Publishing允许我从新章节“客户端验证”的一个食谱中摘录一小部分摘录。 这将有助于使读者知道这本书的内容。 在此博客文章中,我想讨论使用Bean验证扩展的PrimeFaces客户端验证(CSV)。

Bean Validation是一个验证模型,可作为Java EE 6平台的一部分使用,它允许通过约束将字段,方法或类上的批注形式的验证。 JSF 2.2支持对托管bean以及Spring或CDI bean中的字段(属性及其getter / setter)的验证。 只要不使用OmniFaces之类的实用程序,尚不支持在类级别进行验证。

PrimeFaces的CSV具有与Bean验证的内置集成。 注释定义的约束可以通过CSV框架在客户端进行验证。 尽管Bean Validation API定义了一整套标准约束注释,但可以轻松想到这些标准注释不足的情况。 对于这些情况,您可以为特定的验证要求创建自定义约束。 PrimeFaces中的客户端验证API与自定义约束无缝协作。

在本食谱中,我们将开发一种特殊的自定义约束和验证器,以验证卡验证码( CVC )。 CVC用作带有银行卡号的安全功能。 它是一个长度在三到四位数之间的数字。 例如,万事达卡或维萨卡要求输入三位数,而美国运通卡要求输入四位数。 因此,CVC验证将取决于所选的银行卡。 用户可以通过p:selectOneMenu选择银行卡,然后在p:inputText中输入CVC,然后提交输入。

怎么做…

我们将从用于CVC字段的自定义注释开始。

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验证API的常规注解,而@ClientConstraint是PrimeFaces CSV框架的注解,它有助于解析元数据。 开发的注释定义消息密钥invalid.cvc.message并且具有Custom属性forCardMenu 。 此属性的值是任何有关PrimeFaces Selectors (PFS)搜索表达式,用于引用银行卡的选择菜单。 这是必需的,因为有效的CVC值取决于所选的卡。

CvcConstraintValidator的目标是验证输入长度。

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的目标是准备元数据。

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();}
}

让我们转到客户端实现。 首先,我们必须创建一个JavaScript文件,说validators.js ,并命名空间中的注册有自己的验证PrimeFaces.validator名为ValidCVC 。 此名称是由getValidatorId()方法返回的唯一ID(请参阅类CvcClientConstraint )。 要实现的功能称为validate() 。 它有两个参数:元素本身和要验证的当前输入值。

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);}}
};

其次,我们必须为本地化消息创建一个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具有两个必需属性,并用@NotNull注释。 另外,属性cvc带有我们的自定义注释@ValidCVCforCardMenu的属性forCardMenu指向列出可用银行卡的p:selectOneMenu的样式类。

@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片段中,我们有一个带有两个银行卡的选择菜单和一个CVC输入字段。 p:commandButton验证字段并在回发时执行方法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}"/>

注意:如您所见, p:selectOneMenup:inputText指定必需的属性。 我们可以实现的转变@NotNull注释与价值所需要的属性, true ,如果我们设置的参数范围内primefaces.TRANSFORM_METADATAtrue

在最后一步中,所有必需JavaScript文件都必须包含在页面上。

<h:outputScript library="js" name="chapter10/lang_en.js"/>
<h:outputScript library="js" name="chapter10/validators.js"/>

下两张图片显示验证失败时会发生什么

3427_10_04

3427_10_05

如果一切正常,则出现一个带有已保存文本的警告框。 向用户显示。

3427_10_06

怎么运行的…

消息密钥invalid.cvc.message和文本应放在名为ValidationMessages资源包中,例如ValidationMessages_en.propertiesValidationMessages是Bean验证规范中指定的标准名称。 属性文件应位于应用程序类路径中,并包含以下条目: invalid.cvc.message=Card Validation Code is invalid 。 此配置对于服务器端验证很重要。

CvcClientConstraint中的getMetadata()方法提供了一个具有名称,值对的映射。 元数据在呈现HTML中公开。 可以通过element.data(name)在客户端访问这些值,其中element是基础本机HTML元素的jQuery对象。 具有元数据的CVC字段呈现为

<input type="text" data-forcardmenu="@(.card)"data-p-con="javax.faces.Integer" data-p-required="true"...>

最有趣的部分是客户端验证器的实现。 要验证的值已经是数字,因为首先它由PrimeFaces的内置客户端转换器针对数据类型java.lang.Integer转换。 我们只需要检查该值是否为正且具有有效长度。 有效长度取决于菜单p:selectOneMenu中所选的卡片,PrimeFaces JavaScript API可以使用PrimeFaces.expressions.SearchExpressionFacade.resolveComponentsAsSelector(selector)对其进行访问,其中选择器是任何PrimeFaces选择器,在我们的示例中为@(.card) 。 如果验证失败,则通过引发throw PrimeFaces.util.ValidationContext.getMessage(text, parameter)引发异常。

通过在p:commandButton上设置validateClient=”true”来触发客户端验证。

翻译自: https://www.javacodegeeks.com/2015/01/extending-primefaces-csv-with-bean-validation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET.CORE发布后启动网站出现500.19-0x8007000d错误解决方法

本项目使用的是netcoreapp2.2&#xff0c;缺少的XML文件是swagger。发布采用的是文件系统、依赖框架。 我第一次发布asp.net.core的后台&#xff0c;发布后启动网站出现500.19错误-0x8007000d。百度查了一下原因&#xff0c;2其中大多数人说是因为没有权限&#xff0c;需要编辑…

WildFly和Docker上的Java EE 7动手实验室

Java EE 7动手实验室已在全球范围内交付&#xff0c;它是一个非常标准的应用程序&#xff0c;显示了典型Java EE 7应用程序的设计模式和反模式。 它显示了如何在接近现实的应用程序中使用以下技术&#xff1a; WebSocket 1.0 JSON处理1.0 批次1.0 上下文和依赖注入1.1 Jav…

一罐将其全部统治:Arquillian + Java 8

借助Java 8 &#xff0c;已实现了许多新的语言改进&#xff0c;以简化开发人员的生活。 在我看来&#xff0c; Java 8的最大优点之一是&#xff0c;在某些情况下&#xff0c;已开发的代码看起来比使用以前的方法更漂亮&#xff0c;我指的是Lambdas和Method引用。 这篇文章不是要…

uni-app引入阿里巴巴矢量库图标后,顶部导航栏显示小方块

引入阿里巴巴矢量图标库 首先在阿里巴巴创建项目&#xff0c;拥有图标 具体引入方法参考&#xff1a; [https://blog.csdn.net/Dream_Weave/article/details/88550978?depth_1-utm_sourcedistribute.pc_relevant.none-task&utm_sourcedistribute.pc_relevant.none-task]在…

使用Spring Integration进行消息处理

Spring Integration提供了Spring框架的扩展&#xff0c;以支持著名的企业集成模式。 它在基于Spring的应用程序中启用轻量级消息传递&#xff0c;并支持与外部系统的集成。 Spring Integration的最重要目标之一是为构建可维护且可测试的企业集成解决方案提供一个简单的模型。 …

使用RxNetty访问Meetup的流API

本文将涉及多个主题&#xff1a;响应式编程&#xff0c;HTTP&#xff0c;解析JSON以及与社交API集成。 完全在一个用例中&#xff1a;我们将通过非夸张的RxNetty库实时加载和处理新的metup.com事件&#xff0c;结合Netty框架的强大功能和RxJava库的灵活性。 Meetup提供了公开可…

js、react对象名和对象属性赋值

const resValue {}; resValue[standards${standardsNumber}] ""; Console.log(:test"&#xff0c;resValue )//

TIBCO产品的微服务和DevOps

如今&#xff0c;每个人都在谈论微服务。 您可以在数百篇文章和博客文章中读到很多有关微服务的信息。 马丁福勒 &#xff08; Martin Fowler &#xff09;的文章是一个很好的起点&#xff0c;该文章引发了有关这种新架构概念的大量讨论。 另一个很棒的资源是独立于供应商的分…

使用Degraph管理软件包依赖关系

软件开发领域的很大一部分是使系统的复杂性尽可能地低。 但是复杂性到底是什么&#xff1f; 虽然确切的语义有很大不同&#xff0c;但取决于您询问的人&#xff0c;大多数人可能都认为这与系统中部件的数量及其交互有很大关系。 考虑太空中的大理石&#xff0c;即行星&#xf…

[转载] 应急管理体系及其业务流程研究

转载于:https://www.cnblogs.com/6DAN_HUST/archive/2013/03/04/2942337.html

WP8手机上的图标

一直不清楚WP8手机上两个圆的标志是什么意思&#xff0c;今天看到下面的链接&#xff0c;终于搞明白了&#xff0c;原来是打开了GPS就有。 http://www.windowsphone.com/en-us/how-to/wp8/basics/what-do-the-icons-on-my-phone-mean 转载于:https://www.cnblogs.com/wonderow/…

ASIHTTPRequest类库简介和使用说明

官方网站&#xff1a; http://allseeing-i.com/ASIHTTPRequest/ 。可以从上面下载到最新源码&#xff0c;以及获取到相关的资料。 使用iOS SDK中的HTTP网络请求API&#xff0c;相当的复杂&#xff0c;调用很繁琐&#xff0c;ASIHTTPRequest就是一个对CFNetwork API进行了封装&a…

UltraESB的首选IDE – IntelliJ IDEA

在AdroitLogic&#xff0c;我们长期以来一直在使用IntelliJ IDEA进行开发。 它是Java和相关语言/技术的最佳IDE&#xff08;它可能也是许多其他语言的选择&#xff0c;但我的经验主要是Java和相关技术&#xff09;。 Groovy和IDEA的Grails的集成很棒。 通过自动发现JDBC驱动程…

跟我一步一步开发自己的Openfire插件

这篇是简单插件开发&#xff0c;下篇聊天记录插件。 开发环境&#xff1a; System&#xff1a;Windows WebBrowser&#xff1a;IE6、Firefox3 JavaEE Server&#xff1a;tomcat5.0.2.8、tomcat6 IDE&#xff1a;eclipse、MyEclipse 8开发依赖库&#xff1a; Jdk1.6、jasper-com…

Apache FOP与Eclipse和OSGi的集成

Apache FOP是由XSL格式化对象&#xff08; XSL-FO &#xff09;驱动的开源打印处理器。 例如&#xff0c;将数据对象转换为PDF可能非常有用。 但是&#xff0c;将其集成到PDE中并最终以OSGi Service的形式运行并最终显得有些麻烦。 因此&#xff0c;我提供了一个P2存储库&…

不删除侦听器–使用ListenerHandles

听一个可观察的实例并对它的变化做出反应很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。 总览 这篇文章将首先讨论这种情况&#xff0c;然后再讨论常见的方法和问题所在。 然后&#xff0c;它将提供解决大多数问题的简单抽象…

使用Google Guava Cache进行本地缓存

很多时候&#xff0c;我们将不得不从数据库或另一个Web服务获取数据或从文件系统加载数据。 在涉及网络呼叫的情况下&#xff0c;将存在固有的网络等待时间&#xff0c;网络带宽限制。 解决此问题的方法之一是在应用程序本地拥有一个缓存。 如果您的应用程序跨越多个节点&…

JAX-RS 2.0:服务器端处理管道

这篇文章的灵感来自JAX-RS 2.0规范文档 &#xff08;附录C&#xff09;中的Processing Pipeline部分。 我喜欢它是因为它提供了JAX-RS中所有模块的漂亮快照-以准备好吞咽的胶囊形式&#xff01; 礼貌– JAX-RS 2.0规范文档 因此&#xff0c;我想到了使用此图简要概述不同的JA…

基于TCP/IP的文件服务器编程一例

来源&#xff0c;华清远见嵌入式学院实验手册&#xff0c;代码来源&#xff1a;华清远见曾宏安 实现的功能&#xff1a; 编写TCP文件服务器和客户端。客户端可以上传和下载文件 客户端支持功能如下&#xff1a; 1.支持一下命令 help 显示客户端所有命令和说明 list 显示服务器…

【Linux系统基础】(2)在Linux上部署MySQL、RabbitMQ、ElasticSearch、Zookeeper、Kafka、NoSQL等各类软件

实战章节&#xff1a;在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;…