• 资源链接
  • Bean Validation简介
  • Bean Validation的特点
  • Bean Validation的配置
  • Bean Validation的用法
    • 最简单的用法
    • 自定义错误提示信息
    • 在方法上面添加注解

资源链接

Bean Validation 官网地址:

  • Bean Validation 官网

Hibernate Validator 官方文档地址:

  • Hibernate Validator官方文档

validation api 文档地址:

  • validation api 文档

码云测试代码地址:

  • validation

Bean Validation简介

  验证数据是在所有应用程序层中出现的常见任务,从表示到持久化层。通常,在每个层中实现相同的验证逻辑,这是耗时且容易出错的。为了避免重复这些验证,开发人员经常将验证逻辑直接绑定到域模型中,使用验证代码将域类与类本身的元数据绑定在一起。

  JSR 380-Bean验证2.0-为实体和方法验证定义了元数据模型和API。默认的元数据源是注释,可以通过使用XML覆盖和扩展元数据。API不绑定到特定的应用程序层或编程模型。它不是与web或持久性层绑定的,它既可以用于服务器端应用程序编程,也可以用于富客户端Swing应用程序开发人员。

  Hibernate Validator 6和Bean Validation 2.0需要Java 8或更高版本。

Bean Validation的特点:

  Bean Validation 验证符合标准的Java规范

  • 让您通过注释来表达对对象模型的约束

  • 让您以可扩展的方式编写自定义约束

  • 提供用于验证对象和对象图的api

  • 提供用于验证参数和返回方法和构造函数值的api

  • 报告一组违规(本地化)

  • 运行在Java SE上,但是集成在Java EE 6和以后;Bean验证2.0是Java EE 8的一部分

Bean Validation的配置

  我们以Maven项目为例来进行说明,Bean Validation在使用时需要添加以下依赖项:分别是javax.validation中的validation-api以及org.hibernate.validator中的hibernate-validator

  而下面的org.glassfish中的javax.el不属于Bean Validation,但是在一些情况下它是必须的,因为Bean Validation需要EL表达式相应的支持,当然,对于提供EL表达式的容器,该依赖就可以不用添加了。

<!-- https://mvnrepository.com/artifact/javax.validation/validation-api --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.7.Final</version></dependency><!--统一的EL参考实现的Maven依赖关系--><!--对于那些无法提供EL实现的环境,Hibernate验证器提供了一个章节的相应介绍。然而,这个插值器的使用不符合Bean验证规范。--><dependency><groupId>org.glassfish</groupId><artifactId>javax.el</artifactId><version>3.0.1-b08</version></dependency>

  下面是完整的pom.xml源码:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.lyc</groupId><artifactId>validation</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>validation</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/javax.validation/validation-api --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.7.Final</version></dependency><!--统一的EL参考实现的Maven依赖关系--><!--对于那些无法提供EL实现的环境,Hibernate验证器提供了一个章节的相应介绍。然而,这个插值器的使用不符合Bean验证规范。--><dependency><groupId>org.glassfish</groupId><artifactId>javax.el</artifactId><version>3.0.1-b08</version></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><!-- lombok 插件 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.20</version><scope>provided</scope></dependency><!--logback--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.1.8</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.8</version></dependency><!--slf4j不属于logback,但是通常是slf4j配合logback一起来进行使用的--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.22</version></dependency></dependencies>
</project>

Bean Validation的用法

最简单的用法

  我们以下面的官网示例代码Car.java为例来进行说明:

package com.lyc.validator.entity;import lombok.Getter;
import lombok.Setter;import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;@Getter
@Setter
public class Car {@NotNullprivate String manufacturer;@NotNull@Size(min = 2, max = 14)private String licensePlate;@Min(2)private int seatCount;public Car(String manufacturer, String licencePlate, int seatCount) {this.manufacturer = manufacturer;this.licensePlate = licencePlate;this.seatCount = seatCount;}}

  其中@NotNull, @Size 和 @Min注解用于声明应用于Car实体类的字段约束条件。

  • manufacturer:必须不能为空
  • licensePlate:必须不能为空,同时还应满足字符串长度介于2和14个长度之间
  • seatCount:必须至少为2

  下面是创建的对于Car实体类的测试代码:

package com.lyc.validator;import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;import com.lyc.validator.entity.Car;
import lombok.extern.slf4j.Slf4j;
import org.junit.BeforeClass;
import org.junit.Test;import static org.junit.Assert.assertEquals;@Slf4j
public class CarTest {private static Validator validator;@BeforeClasspublic static void setUpValidator() {ValidatorFactory factory = Validation.buildDefaultValidatorFactory();validator = factory.getValidator();}@Testpublic void manufacturerIsNull() {Car car = new Car( null, "DD-AB-123", 4 );Set<ConstraintViolation<Car>> constraintViolations =validator.validate( car );assertEquals( 1, constraintViolations.size() );String errMessage = constraintViolations.iterator().next().getMessage();assertEquals( "不能为null", errMessage);log.info(errMessage);}@Testpublic void licensePlateTooShort() {Car car = new Car( "Morris", "D", 4 );Set<ConstraintViolation<Car>> constraintViolations =validator.validate( car );assertEquals( 1, constraintViolations.size() );String errMessage = constraintViolations.iterator().next().getMessage();assertEquals("个数必须在2和14之间", errMessage);log.info(errMessage);}@Testpublic void seatCountTooLow() {Car car = new Car( "Morris", "DD-AB-123", 1 );Set<ConstraintViolation<Car>> constraintViolations =validator.validate( car );assertEquals( 1, constraintViolations.size() );String errMessage = constraintViolations.iterator().next().getMessage();assertEquals("最小不能小于2", errMessage);log.info(errMessage);}@Testpublic void carIsValid() {Car car = new Car( "Morris", "DD-AB-123", 2 );Set<ConstraintViolation<Car>> constraintViolations =validator.validate( car );assertEquals( 0, constraintViolations.size() );}
}

  在setUp()方法中,从ValidatorFactory检索验证器对象。一个验证器实例是线程安全的,并且可以多次重用。因此,它可以安全地存储在静态字段中,并在测试方法中使用,以验证不同的Car实例。

  validate()方法返回一组约束条件实例,您可以对这些实例进行迭代,以查看发生了哪些验证错误。前三个测试方法显示了一些预期的约束违反,最后一个则是展示的正确的测试。

自定义错误提示信息

  Bean Validation在默认的情况下有一些自带的提示信息,如果我们感觉该提示信息并不是很友好,那么我们可以自定义自己的提示信息内容,下面我们以创建实体类Car2为例来进行说明。

package com.lyc.validator.entity;import lombok.Getter;
import lombok.Setter;import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;@Getter
@Setter
public class Car2 {@NotNull(message = "manufacturer字段不能为空!")private String manufacturer;@AssertTrue(message = "isRegistered字段必须为true!")private boolean isRegistered;public Car2(String manufacturer, boolean isRegistered) {this.manufacturer = manufacturer;this.isRegistered = isRegistered;}}

  下面是对Car2的测试代码:

package com.lyc.validator;import com.lyc.validator.entity.Car2;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;@Slf4j
public class Car2Test {private static Validator validator;@BeforeClasspublic static void setUpVolidator(){ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();validator = (Validator) validatorFactory.getValidator();}@Testpublic void manufacturerNull(){Car2 car2 = new Car2(null,true);Set<ConstraintViolation<Car2>> constraintViolations= validator.validate(car2);Assert.assertEquals(1,constraintViolations.size());String errorMessage = constraintViolations.iterator().next().getMessage();log.info(errorMessage);Assert.assertEquals("manufacturer字段不能为空!",errorMessage);}@Testpublic void AssertToTrue(){Car2 car2 = new Car2("Morris",false);Set<ConstraintViolation<Car2>> constraintViolations= validator.validate(car2);Assert.assertEquals(1,constraintViolations.size());String errorMessage = constraintViolations.iterator().next().getMessage();log.info(errorMessage);Assert.assertEquals("isRegistered字段必须为true!",errorMessage);}}

  在上面的代码中,我们通过在注解的后面添加参数message,将我们想要的输出信息写入即可,这样在校验Car2中的信息时,默认的错误提示信息会被我们所写的所覆盖,这样就可以一旦有错误信息时,我们便可以第一时间查看到相应的信息。

在方法上面添加注解

  上面的示例中,所添加注解的地点都是在字段之中进行的,其实我们除了可以在字段中添加注解之外,我们其实还是可以在方法中添加注解信息的,如下所示的Car3实体类中的实例就是如此。

package com.lyc.validator.entity;import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;public class Car3 {private String manufacturer;private boolean isRegistered;public Car3(String manufacturer, boolean isRegistered) {this.manufacturer = manufacturer;this.isRegistered = isRegistered;}@NotNull(message = "manufacturer字段不能为空!")public String getManufacturer() {return manufacturer;}public void setManufacturer(String manufacturer) {this.manufacturer = manufacturer;}@AssertTrue(message = "isRegistered字段返回值为true!")public boolean isRegistered() {return isRegistered;}public void setRegistered(boolean isRegistered) {this.isRegistered = isRegistered;}}

  下面是对Car3的测试源码。

package com.lyc.validator;import com.lyc.validator.entity.Car3;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;@Slf4j
public class Car3Test {private static Validator validator;@BeforeClasspublic static void setUpVolidator(){ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();validator = (Validator) validatorFactory.getValidator();}@Testpublic void manufacturerNull(){Car3 car3 = new Car3(null,true);Set<ConstraintViolation<Car3>> constraintViolations= validator.validate(car3);Assert.assertEquals(1,constraintViolations.size());String errorMessage = constraintViolations.iterator().next().getMessage();log.info(errorMessage);Assert.assertEquals("manufacturer字段不能为空!",errorMessage);}@Testpublic void AssertToTrue(){Car3 car3 = new Car3("Morris",false);Set<ConstraintViolation<Car3>> constraintViolations= validator.validate(car3);Assert.assertEquals(1,constraintViolations.size());String errorMessage = constraintViolations.iterator().next().getMessage();log.info(errorMessage);Assert.assertEquals("isRegistered字段返回值为true!",errorMessage);}}

  如上所示,我们通过在实体类的get方法上添加相应的注解,其实这和在字段中添加注解一样,都是可用的。

Bean Validation相关推荐

  1. java validation_java bean validation 参数验证

    一.前言 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间 ...

  2. JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  3. JSR380(Bean Validation 2.0)

    1.新的变化 支持验证容器元素 集合类型的级联验证. 支持java.util.Optional 支持JavaFX的属性类型 支持自定义容器类型 支持新的日期/时间类型 新的内置约束:@Email, @ ...

  4. JSR349(Bean Validation 1.1)

    1.新增变化 1.1 依赖注入 Bean Validation使用组件MessageInterpolator, TraversableResolver, ParameterNameProvider, ...

  5. JSR303(Bean Validation 1.0)

    Bean Validation的1.0版本 1.约束定义 1.1 约束注解 Constraint 可用于字段.方法.属性.类型.注解类型,validatedBy返回的是ConstraintValida ...

  6. Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

    http://sishuok.com/forum/blogPost/list/7798.html 在之前的<跟我学SpringMVC>中的<第七章 注解式控制器的数据验证.类型转换及 ...

  7. JSR 303 – Bean Validation 介绍及最佳实践

    关于 Bean Validation 在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的.在通常的情况下 ...

  8. JSR 303 - Bean Validation 介绍及最佳实践

    关于 Bean Validation 在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的.在通常的情况下 ...

  9. JSR303—Bean Validation验证

    JSR-303 Bean Validation 是 JAVA EE 6 中的一项子规范 官方参考实现是Hibernate Validator 此实现与 Hibernate ORM 没有任何关系 Bea ...

  10. Java数据校验(Bean Validation / JSR303)

    文档: http://beanvalidation.org/1.1/spec/ API : http://docs.jboss.org/hibernate/beanvalidation/spec/1. ...

最新文章

  1. leetcode算法题--验证二叉树的前序序列化
  2. [CODEVS 3037] 线段覆盖 5
  3. SQL文档阅读笔记-对水平分区和垂直分区理解
  4. Qt学习笔记-使用shape() 使得碰撞更加精确
  5. RobotStudio传送带设计
  6. [网络流24题] 最长k可重线段集问题 (费用流)
  7. RTSP-传送ACC音频文件
  8. vue使用下载插件来完成下载文件
  9. 豆瓣电影、纪录片、书籍......下载神器
  10. 【图纸加密】命令lockdwg转换为多重属性块
  11. [Java] POJ 2387 最短路问题
  12. Linux部署单体架构,从单体式架构迁移到微服务架构:三个策略叙述
  13. SAP合同类型的使用
  14. 将图和双向transformers融合的分子性质预测新工具 简称AGBT - 论文阅读
  15. android开发 实现动态获得app的cpu占有率并导出文件的两种方法。
  16. 企业微信H5踩坑指南
  17. VS2019调试:当前页面的脚本发生错误
  18. ICLR 2021杰出论文公布:清华、上财校友一作获奖
  19. iOS备忘录之iOS目录位置
  20. 第一次仿写小米官方首页总结

热门文章

  1. 野蛮人传教士问题(上)
  2. java技术英文名词读音_Java开发,Java development,音标,读音,翻译,英文例句,英语词典...
  3. Mac安装移动硬盘win10系统
  4. Macbook外接windows键盘,设置快捷键
  5. 稻盛和夫:中国企业如何在萧条中实现大飞跃
  6. 【vant】爬坑引用本地图片
  7. 伯努利分布、二项分布、多项分布、Beta分布、Dirichlet分布、连续分布(正态分布)、大数定理、中心极限定理、贝叶斯理论
  8. 单片机 TDA8023 读 ic 卡 smrat card sync_card
  9. c语言函数声明大全及详解,C语言之函数的声明详解
  10. Memcached详解