前言

在应用程序的业务逻辑中,经常会碰到需要校验参数的情况。
经常要判断一个 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;

深入Java泛型(六):Bean强转原理实践相关推荐

  1. java泛型的作用和实现原理_java泛型的作用及实现原理

    一.泛型的介绍 泛型是Java 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Ja ...

  2. Java Servlet(六):HttpServlet实现原理(jdk7+tomcat7+eclipse)

    本篇记录了HttpServlet的实现过程,主要讲述了如何依赖Servlet,GenericServlet实现的原理. HttpServlet实现过程: 1.是一个Servlet,继承自Generic ...

  3. 轻触开源(一)-Java泛型Type类型的应用和实践

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处:https://my.oschina.net/u/874727/blog/747427 Q:102525062 ...

  4. java 泛型 type_轻触开源(一)-Java泛型Type类型的应用和实践

    转载请注明出处:https://my.oschina.net/u/874727/blog/747427 Q:1025250620 在很多Java的开源项目中都用到Java的泛型.比如Gson,就可以通 ...

  5. java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

    原 java泛型(二).泛型的内部原理:类型擦除以及类型擦除带来的问题 2012年08月29日 23:44:10 Kilnn 阅读数:56717 版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  6. Java泛型的实现原理

    由于前一段时间发现公司有些代码重复性很大,可以使用泛型方法简化,所以向领导提出,领导就让我整理了一下关于泛型的只是分享给大家. 一.Java泛型介绍 泛型是Java 1.5的新特性,泛型的本质是参数化 ...

  7. 大白话说Java泛型:入门、使用、原理

    文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java泛型:入门.使用.原理> 远在 JDK 1.4 版本的时候,那时候是没有泛型的概念的.当时 Java 程序员们写集合类的代码都 ...

  8. java泛型实例化_如何实例化泛型spring bean?

    我想创建一个泛型类,它将帮助我减少样板代码.我正在使用Spring 3(MVC)和Hibernate 4.如何实例化泛型spring bean? 类看起来是这样的: @Repository(" ...

  9. Java 泛型(Generics) 综述

    一. 引子 一般的类和方法,只能使用具体类型:要么是基本类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 多态 算是一种泛化机制,但对代码的约束还是太强 ...

最新文章

  1. hnswlib RuntimeError: Cannot return the results in a contigious 2D array. Probably ef or M is to sma
  2. Spring学习-理解IOC和依赖注入
  3. Python之深入解析Python技能树的测评分析
  4. canal数据同步(客户端代码编写)
  5. oracle如何处理死锁,Oracle死锁处理实例
  6. 休眠事实:了解刷新操作顺序很重要
  7. python学习的一个定位_python学习之——selenium元素定位
  8. 靶形数独(信息学奥赛一本通-T1447)
  9. 双系统win7时间造8小时问题的解决
  10. 给机器人罗宾写一封英语回信_英语作文回信范文英语回信范文
  11. 虚拟机VMware破解版教程下载
  12. Win11如何查看硬盘型号?Win11查看硬盘型号步骤
  13. html5 保存后退,Html5 页面后退并刷新
  14. 地理信息系统GIS小结
  15. 基于xc7k325t fbg900的IBRET的测试流程
  16. R语言广义加性模型GAMs分析温度、臭氧环境数据绘制偏回归图与偏残差图
  17. pacemaker和keepalived的区别
  18. Pandas项目实战1——好莱坞百万级电影评论数据分析
  19. 论文阅读: Towards Automatic Face-to-Face Translation
  20. 理解git fetch, git pull 以及 FETCH_HEAD的含义

热门文章

  1. 远程计算机管理权限,肿么获得远程计算机管理员权限
  2. 下列有关mysql数据库中的null值_MySQL数据库中与 NULL值有关的问题
  3. 简述用决策表设计测试用例的步骤_决策表快速入门
  4. python开发环境和运行环境的区别_Django 开发环境与生产环境的区分详解
  5. ANSYS报错Accelerations are exceeding internal limit解决方法
  6. 添加javascript代码:_JavaScript的使用
  7. linux安装mysql5.6.26_linux mysql-5.6.26 安装
  8. 利用大数据技术探索“数字公民”创新
  9. ZeroClipboard跨浏览器复制粘贴
  10. windows环境下redis.conf配置文件