• 资源链接
  • 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. Linkedin 工程师如何优化他们的 Java 代码
  2. LAMP:用yum安装
  3. Android中对同一个TextView设置不同字体样式
  4. IOS开发中单例模式使用详解
  5. linux函数 取值溢出,Linux eCryptfs工具parse_tag_3_packet()函数堆溢出漏洞
  6. java以下属于合法标识符的是_2012年计算机二级Java合法标识符章节练习题及答案...
  7. 字符编码 and cpp
  8. 平台: pSeries AIX 4.3 AIX 5L
  9. 存储基础知识 - 网络存储主要技术
  10. 小程序在开发者工具、真机测试时好好的,体验版 页面空白无法通过审核
  11. 【多目标优化】Pareto最优解很少
  12. Android 开发基于 Jenkins 实现持续集成
  13. DLL注入与隐藏的学习
  14. SpringBoot 异步接口
  15. Numpy:repeat用法图解
  16. Android Study Material Design 十 再探沉浸式
  17. 2019级C语言大作业 - 泡泡龙
  18. 为什么 Java 仍将是未来的主流语言?
  19. 知识大爆炸时代的解决方案
  20. Serializable接口实现深度克隆

热门文章

  1. 信噪比与雷达探测距离之间关系
  2. C-COT -- 超越相关滤波:学习连续卷积算子(Continuous Convolution Operators)
  3. SPOJ COT 10628 Count on a tree
  4. 【容器化部署简介】 基于腾讯云TKE: kubernetes(k8s), github actions, devops
  5. sqlplus 执行脚本经验总结
  6. python 爬取图片、没有后缀名_python爬虫,图片是无格式的
  7. k8s教程01(k8s环境配置及私有仓库搭建)
  8. Spark多行合并一行collect_list使用
  9. php-screw 安装,liunx 下安装 php_screw 扩展 以及报错处理
  10. memcached 配置