实战:Bean的数据完整性验证方法| 从开发角度看应用架构11

前言

本文仅代表作者的个人观点;

本文的内容仅限于技术探讨,不能作为指导生产环境的素材;

本文素材是红帽公司产品技术和手册;

本文分为系列文章,将会有多篇,初步预计将会有26篇。

二、Bean验证

Java应用程序将数据存储在Java对象中。这些Java对象通过网络,作为参数传递给方法,并存在于Java EE应用程序的不同层中。为了保持数据完整性,数据验证是应用程序逻辑的主要要求。开发人员需要在应用程序的不同层中编写数据验证代码以进行数据验证,这容易出错并且非常耗时。提供bean验证API规范是为了避免代码重复并简化数据验证。 Bean验证是一种通过使用可以应用预定义约束的内置和自定义注释来验证Java对象中的数据的模型。 Bean验证对于Java EE和Java Web应用程序的所有层都是通用的。 Java在JSR 349中提供了bean验证1.1 API .JPA通过bean验证API支持实体类的运行时验证。 JBoss EAP完全符合JSR 349。

Bean验证约束和注释

验证约束是用于验证数据的规则。这些约束以注释的形式应用于属性、方法、属性或构造函数。 Bean验证1.1允许对参数使用验证约束并返回方法和构造函数的返回值。 Java提供内置约束,并且还支持用户定义的自定义约束。 javax.validation.constraints包中包含几个内置约束。一些常见的注释:

所有bean验证注释都具有可选属性,例如message属性,如果验证失败,可用于显示自定义消息。某些注释具有必需属性。例如,DecimalMax注释具有String类型的value属性以表示最大值。一些例子如下: 如果验证失败,带有message属性的@NotNull可以显示可以显示的自定义消息,而不是默认消息。

@NotNull(message="Address cannot be a null value")
private Address address;

三、自动调用与手工调用

自动调用

Java EE 7应用程序服务器提供Hibernate Validator包,其中包括bean验证注释以及验证约束的自动调用。将注释附加到实体字段时,Hibernate会自动验证数据是否与字段上的注释约束相匹配。例如,以下代码演示了如何使用@Size(min = 4)约束,将其应用于Person类的personName属性。在创建实体的实例时,如果呈现的数据不符合验证约束,在这种情况下,String的大小至少为四个字符,则返回错误。在将实体持久保存到数据库之前,应用程序服务器和验证器框架会自动检查约束。

...
    //Using validation in constructor
    public Person(@NotNull String personName){
       this.personName=personName;
    }

    //using validation in method parameter
    public void setPersonName(@Size(min=4) String name){
       this.personName=personName;
    }
  ...

手动调用

虽然许多框架基于这些验证注释自动验证实体字段,但有时开发人员需要以编程方式触发bean验证。要以编程方式验证实体的实例,请使用javax.validation.Validator API。验证器接口提供验证整个实体或实体的单个属性的方法。以下代码说明了如何创建ValidatorFactory和Validator实例并使用验证器验证对象。

...
  Person p = new Person();
  p.setPersonName("RH");
  ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
  Validator validator = validatorFactory.getValidator();
  Set<ConstraintViolation<Person>> constraintViolations = validator.validate(p);
  ...

此代码创建一组ContstraintViolations,可以迭代这些ContstraintViolations以查看基于实体注释发生的所有违规。以下是迭代约束保护集并记录每个错误的示例:

for (ConstraintViolation<Person> cv : constraintViolations) {
    log.error(cv.getMessage());
}

四、实验展现:增加一个约束条件

在JBDS中导入现有maven项目:

将验证约束添加到Person实体类,以确保personName不为空。

首先import约束的library :

然后在class中使用这个约束:

也就是说,当输入的内容是空的时候,发出消息:ha:Name Can not be blank

接下来,启动app server,然后编译和部署应用。

部署应用:

查看EAP的日志:

通过浏览器访问应用:

第一次,我先不输入任何内容点击Submit,看返回结果:

返回内容和我在源码中写的约束是一致的。

输入符合约束的内容,不会报错:

五、实验展现:增加第二个约束条件

在源码中import第二个库:

在源码中引用这个约束:

也就说,当输入的信息少于两个字符的时候会报错,报错信息:ha:Name can not be less than 2 characters

重新构建代码:

部署应用:

查看EAP日志,war包部署成功:

浏览器访问,输入一个字符v,点击submit:

报错信息和我在源码中定义的是一致的。

魏新宇

  • 红帽资深解决方案架构师
  • 专注开源云计算、容器及自动化运维在金融行业的推广
  • 拥有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鉴定级)等管理认证。
  • 拥有红帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技术认证。

原文发布于微信公众号 - 大魏分享(david-share)

原文发表时间:2018-07-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ml

javaSE基础——常见的dos命令即其他

    常用的DOS命令    dir(directory) :    列出当前目录下的文件以及文件夹  md(make directory) : 创建目录...

35370
来自专栏JavaEdge

大道缓存1 缓存特征2 缓存介质3 缓存分类和应用场景缓存实战

用户请求从界面(浏览器/App)到网络转发、应用服务再到存储(数据库或文件系统),然后返回到界面呈现内容。

14010
来自专栏cloudskyme

jbpm5.1介绍(3)

在您好的应用程序中使用一个新的流程 流程处理  (1)你需要建立一个知识库,其中包含过程定义 KnowledgeBuilder kbuilder = Knowl...

38040
来自专栏白驹过隙

进程同步和线程同步概述

74880
来自专栏张戈的专栏

Linux运维工程师:30道面试题整理

前段时间,我在准备面试的时搜到的一套 Linux 运维工程师面试题,感觉比较全面,一直保存在草稿,刚在整理后台时翻了出来,干脆就发出来好了,以备不时之需。 1....

2.3K50
来自专栏张善友的专栏

关于gcc、glibc和binutils模块之间的关系

一、关于gcc、glibc和binutils模块之间的关系 1、gcc(gnu collect compiler)是一组编译工具的总称。它主要完成的工作任务是“...

26280
来自专栏IMWeb前端团队

RESTful API 规范 v1.0

本文作者:IMWeb 梁伟盛 原文出处:IMWeb社区 未经同意,禁止转载 RESTful API 规范 v1.0 [toc] URI URI规范 不...

31970
来自专栏人人都是极客

Linux 程序编译过程的来龙去脉

大家肯定都知道计算机程序设计语言通常分为机器语言、汇编语言和高级语言三类。高级语言需要通过翻译成机器语言才能执行,而翻译的方式分为两种,一种是编译型,另一种是解...

29230
来自专栏闵开慧

Java heap space

其实这样的错误有时候并不是程序逻辑的问题(当然有可能是由于程序写的不够高效,产生的内存消耗不合理而导致),而是由于同样的作业,在数据量和数据本身发生不同时就会占...

31590
来自专栏微信公众号:Java团长

Java Web从前端到后台常用框架介绍

Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解...

27830

扫码关注云+社区

领取腾讯云代金券