前言

在应用程序的业务逻辑中,经常会碰到需要校验参数的情况。
经常要判断一个 Model 的字段是否为 Null 之类,或者判断长度等。
那么在代码层面上,就会需要编写很多校验,影响代码的阅读以及维护,而且造成代码的冗余。

应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。

在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。

为了更好的关注核心的业务逻辑,减少参数校验侵入方法内部,因此有了 JRS-303 提案。

JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。如果想了解更多有关 Hibernate Validator 的信息,请查看 http://www.hibernate.org/subprojects/validator.html

下载 JSR 303 – Bean Validation 规范 http://jcp.org/en/jsr/detail?id=303
目前最新的为 Bean Validation 2.0,是 JSR 380,实现为 Hibernate Validator - 6.0.1.Final

Bean Validation 2.0 中的 constraint

Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Negative 被注释的元素必须是一个严格的负数,举例,0 被视为无效值,因为不是负数
@NegativeOrZero 被注释的元素必须是一个严格的负数或者 0
@Positive 被注释的元素必须是一个严格的正数,举例,0 被视为无效值,因为不是正数
@PositiveOrZero 被注释的元素必须是一个严格的正数或者 0
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个带小数的数,integer 为整数位最大值,fraction 为小数位最大值
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 被注释的元素必须是一个过去的日期或者现在日期
@Future 被注释的元素必须是一个将来的日期
@FutureOrPresent 被注释的元素必须是一个将来的日期或者现在日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@NotEmpty 被注释的元素必须不为 null 或者不为空,可校验字符、集合、Map
@NotBlank 被注释的元素必须不为空字符串
@Email 被注释的元素必须是电子邮箱地址

Hibernate Validator 附加的 constraint

Constraint 详细信息
@Length 被注释的字符串的大小必须在指定的范围内
@Range 被注释的元素必须在合适的范围内

Spring boot 中使用方式

参数校验

@Slf4j
@Validated // 使用 spring 的 Validated 注解标注此 Controller 是需要执行校验的,
@RestController
@RequestMapping("/demo-1")
public class Demo1Controller {/*** 在参数上做校验,基本类型* @param name 名称** @return*/@GetMapping("/query-1")public HttpStatus query1(@NotBlank(message = "不能为空") String name) {log.info("name is {}", name);return HttpStatus.OK;}}

运行结果:

POJO 校验

@Slf4j
@RestController
@RequestMapping("/demo-2")
public class Demo2Controller {@PostMapping("/save-1")public HttpStatus save1(@Validated Person person) {return HttpStatus.OK;}}@Data
public class Person {@NotBlank(message = "名字不能为空")private String name;private Integer age;private String sex;
}

运行结果:

接口层级校验

@Slf4j
@RestController
@RequestMapping("/demo-3")
public class Demo3Controller {@Resourceprivate DemoService service;@PostMapping("/save-1")public HttpStatus save1(@RequestBody Person person) {log.info("person is {}", person);service.save(person);return HttpStatus.OK;}}@Data
public class Person {@NotBlank(message = "名字不能为空")private String name;private Integer age;private String sex;
}@Validated
public interface DemoService {void save(@Valid Person person);
}

运行结果:

分组校验

@Slf4j
@RestController
@RequestMapping("/demo-4")
public class Demo4Controller {@PostMapping("/save-1")public HttpStatus save1(@Validated(value = {SaveValidation.class, Default.class}) @RequestBody PersonGroup person) {log.info("person is {}", person);return HttpStatus.OK;}@PostMapping("/update-1")public HttpStatus update1(@Validated(value = {UpdateValidation.class, Default.class}) @RequestBody PersonGroup person) {log.info("person is {}", person);return HttpStatus.OK;}}@Data
public class PersonGroup {@NotBlank(groups = {SaveValidation.class}, message = "保存时名字不能为空")private String saveName;@NotBlank(groups = {UpdateValidation.class}, message = "更新时名字不能为空")private String updateName;private Integer age;private String sex;
}

运行结果:

@Validated 隐含默认校验,即默认分组,如果不分场景下校验,可以使用如下方式配置:
分组时:
@Validated(value = {ContainerSaveValidation.class, Default.class})
属性上:
@NotBlank(groups = {SaveValidation.class}, message = "保存时名字不能为空") private String saveName;

参考文章:
https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html
Hibernate Validator 官方文档

Bean Validation 校验实践相关推荐

  1. Java Bean Validation 最佳实践

    <h1 class="postTitle"><a id="cb_post_title_url" class="postTitle2& ...

  2. bean validation校验方法参数_Spring Boot 之使用 validation 验证参数

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq了 ...

  3. bean validation校验方法参数_Spring Validation最佳实践及其实现原理,参数校验没那么简单!

    本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料 顺便再给大家推荐一套Spring ...

  4. bean validation校验方法参数_项目启动时首先校验Spring Boot配置参数

    1. 概述 在项目实际开发过程中,为了更好的复用,我们参考Spring Boot Starters,封装了许多企业内部中间件的starter.这些中间件的接入都需要申请并在项目中配置一些特定的参数.我 ...

  5. Springboot Bean Validation校验框架

    我们的校验框架通常用于DTO层,用户从前端通过Json串传入值,后端对传入的Json封装到DTO层中,我们对DTO层的元素进行校验,比如邮箱,手机号等等. 首先需要引入bean校验需要的jar包: & ...

  6. bean validation校验方法参数_Springboot 使用校验框架validation校验

    作者:双斜杠少年 blog.csdn.net/u012373815/article/details/72049796 b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上 ...

  7. bean validation校验方法参数_SpringBoot参数校验 从入门到精通 解决繁琐的参数验证工作...

    ● 手把手教你实现 SpringBoot与Vue整合开发 前后端分离 简单例子 详解●SQL优化经历  SQL执行效率提高了1000w倍●Java面试题 详解 由易到难● SQL语句大全详解 增删改查 ...

  8. 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知

    乔丹是我听过的篮球之神,科比是我亲眼见过的篮球之神.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免 ...

  9. java输出结果校验_2. Bean Validation声明式校验方法的参数、返回值

    你必须非常努力,才能干起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习. ✍前言 ...

最新文章

  1. 投影幕布jsp_投影 篇一:实测亲证百元投影幕布不如白墙
  2. 【问题解决】微软OneNote使用笔记,Ditto解决OneNote复制粘贴文本输出图片问题
  3. Ubuntu出现卡logo、卡住、黑屏无法正常启动、屏幕和键盘背光无法调节等一系列问题?可能是NVIDIA显卡驱动没装好...
  4. Spring boot优点
  5. python中不具备np_Python中np.random.multivariate_normal问题?
  6. 用原生JavaScript实现淡入淡出轮播图
  7. java给qq发消息_QQ发送消息
  8. 光纤测试仪为什么使用单芯法为光纤损耗测量
  9. connectionstring mysql_Entity Framework 6 自定义连接字符串ConnectionString连接MySQL
  10. c mysql 双主复制_mysql双主复制及使用keepalived作高可用的配置详解
  11. 24 OB22无法修改公司代码的附加本位币从EUR到CNY
  12. python之yield
  13. 一句代码搞定权限请求,从未如此简单
  14. 设置Listview行高--小技巧
  15. Python游戏编程入门(一)——初识Pygame
  16. NC文件数据提取完成(1.16)
  17. BlackBerry 9850 应用:CISCO WebEx会议
  18. 论文笔记(十八):Object Detection and Spatial Location Method for ... Based on 3D Virtual Geographical Scen
  19. win2003的密钥
  20. FPGA实现JPEG-LS图像压缩,有损无损可配置,提供工程源码和技术支持

热门文章

  1. clover删除多余引导_黑苹果CLOVER引导去除多余引导项Windows10+MacOS+DeepinLinux+FydeOS+MintLinux+ManjaroLinux...
  2. CentOS6 64 安装/卸载 JDK
  3. 全国职业院校技能大赛网络建设与运维赛项赛题(四)
  4. 华为云桌面服务器(2288H V5)加装内存条及硬盘简记
  5. 字符头开发实况(5)
  6. 导演路学长追悼会 王小帅现身葛优送花圈
  7. realease包出现–missing type parameter
  8. 发送请求时,postman正常,微信小程序失败?
  9. html 焦点失去时间,详解HTMLonfocus获得焦点和onblur失去焦点事件
  10. mysql 英雄对位胜率