当前位置: 首页 > news >正文

Hibernate Validator 数据校验框架

文章目录

  • 一、数据校验框架简介
    • 1、JSR(Java 规范提案):Bean Validation
    • 2、javax.validation.api
    • 3、jakarta.validation.api
  • 二、SpringBoot基础使用
    • 1、校验get请求参数
    • 2、校验post请求参数
    • 3、常用注解
    • 4、分组校验
    • 5、自定义校验规则
    • 5、校验模式
    • 6、全局异常处理

一、数据校验框架简介

1、JSR(Java 规范提案):Bean Validation

  • JSR:Java Specification Requests的缩写,意思是Java规范提案
    • 是指向JCP(Java Community Process) 提出新增一个标准化技术规范的正式请求
    • 任何人都可以提交JSR,以向Java平台增添新的API和服务
    • JSR已成为Java界的一个重要标准
  • Bean Validation就是这个JSR规范之一
    • Bean Validation是一个运行时的数据验证框架的标准

  JSR303是专家组成员向JCP提交的第1版Bean Validation,即针对bean数据校验提出的一个规范,使用注解方式实现数据校验。后面有升级版本JSR349及JSR380。

JSR # Bean Validation官网地址:https://jcp.org/en/jsr/summary?id=bean+validation

在这里插入图片描述

  • JSR303 Bean Valiadation第一版 伴随着JAVAEE 6在2009年发布,Hibernate实现版本4.3.1.Final
  • JSR349 Bean Valiadation 1.1 伴随着JAVAEE 7在2013年发布,Hibernate实现版本5.1.1.Final
  • JSR380 Bean Valiadation 2.0 伴随着JAVAEE 8在2017年发布,完全兼容低版本的JAVA SE,Hibernate实现版本6.0.1.Final

Bean Valiadation 与 Hibernate Validation

  • JSR(Bean Valiadation)规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,位于javax.validation.constraints包下,只提供规范不提供实现
  • Hibernate Validation是对Bean Valiadation这个规范的实践,提供相应的实现,并增加一些其他校验注解,如@Length,@Range等等,位于org.hibernate.validator.constraints包下

2、javax.validation.api

  • Java在2009年的JAVAEE 6中发布了JSR303以及javax下的validation包内容
  • JSR Bean Validation 2.0 重要版本2.0.1.Final
<dependency>  <groupId>javax.validation</groupId>  <artifactId>validation-api</artifactId>  <version>2.0.1.Final</version>  
</dependency>
  • Bean Validation 2.0中包含的注解

在这里插入图片描述

  • Hibernate-Validator是Hibernate项目中的一个数据校验框架,是Bean Validation一种实现
  • Hibernate-Validator除了提供了JSR 303规范中所有内置constraint的实现,还有一些附加的constraint(约束)
  • JSR Bean Validation 2.0对应hibernate-validator的实现重要版本6.0.16.Final
<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.16.Final</version>
</dependency>
  • Hibernate-Validator 扩展的注解

在这里插入图片描述

  • spring-boot-starter-web 2.1.4.RELEASE引入的就是是这个版本
  • hibernate-validator包下包含了validation-api,这个很好理解,做规范注解的实现肯定需要用到规范中定义的注解

在这里插入图片描述

3、jakarta.validation.api

  • Java8开始,Java EE改名为Jakarta EE,故javax.validation相关的api在jakarta.validation的包下
  • JSR Bean Validation 2.0 重要版本2.0.2
<dependency>  <groupId>jakarta.validation</groupId>  <artifactId>jakarta.validation-api</artifactId>  <version>2.0.2</version>  
</dependency>
  • springboot后面版本不再自动导入hibernate-validator,可以导入spring-boot-starter-validation:2.3.12.RELEASE

在这里插入图片描述

  • 虽然依赖名改为了jakarta,导包还是javax,应该是个过渡吧

在这里插入图片描述

二、SpringBoot基础使用

  • springboot项目导入依赖,低版本不需要导入,spring-boot-starter-web就包含了
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

1、校验get请求参数

  • get请求校验参数类上需要添加@Validated注解
  • @Validated是springmvc提供注解,非javax.validation的注解
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotEmpty;@RestController
@Validated
public class UserController1 {@GetMapping("/getUser")public String getUser(@NotEmpty(message = "name不能为空") @RequestParam("name") String name,@Max(value = 150) @RequestParam("age") Integer age) {return "success";}
}

执行请求:http://localhost:8080/getUser?name=&age=200

  • 校验注解可以设置message属性(抛错提示),也可以不设置(默认中文错误提示)

在这里插入图片描述

2、校验post请求参数

  • post请求校验实体类上前面添加@Valid@Validated注解
    • 两者在这里作用相同,唯一区别是后者可以设置分组,后面会讲
  • @Valid是javax.validation提供注解
import javax.validation.Valid;@RestController
public class UserController2 {@PostMapping("/saveUser")public String saveUser(@Valid @RequestBody User user) {System.out.println(user);return "success";}
}
  • 请求实体添加校验注解
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.Length;import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;@Data
public class User {// 可以为 null,若不为 null,则长度为 [5, 17]@Length(min = 5, message = "userName长度须在[5,17]")private String userName;// @Size不能验证Integer,适用于String、List、Map、数组@Size(min = 1, max = 3, message = "password长度须在[1,3]")private String password;// list 可以为 null,若不为 null,则长度为 [1, 5]@Size(min = 1, max = 5, message = "list的Size在[1,5]")private List<String> list;@NotNull@Valid // 级联校验,该注解将会校验自定义类private DetailInfo detailInfo;
}@Data
class DetailInfo {@NotEmpty(message = "name不能为空")private String name;// 匹配任何数字@Pattern(regexp = "^\\d+$", message = "itemCode需要数字")private String itemCode;@Range(min = 10, max = 100, message = "range在[10,100]之间")private int age;
}

3、常用注解

注解说明支持类型
@Null必须为null
@NotNull必须不为null
@NotEmpty必须不为null且长度大于0String、集合、Map、数组
@NotBlank必须不为null且去除首尾空格后长度大于0String
@AssertTrue必须为trueboolean和Boolean
@AssertFalse必须为falseboolean和Boolean
@Min(value)必须是一个数字
其值必须大于或等于指定的最小值
值为null不校验
String、Number
@Max(value)必须是一个数字
其值必须小于或等于指定的最大值
值为null不校验
String、Number
@DecimalMin(value)必须是一个数字
其值必须大于或等于指定的最小值(支持小数)
值为null不校验
String、Number
@DecimalMax(value)必须是一个数字
其值必须小于或等于指定的最大值(支持小数)
值为null不校验
String、Number
@Size(max, min)元素的大小必须在指定的范围内
值为null不校验
String、集合、Map、数组
@Pattern(regexp = )正则表达式校验
值为null不校验
@Digits(integer,fraction)验证整数位数和小数位数上限
值为null不校验
String、Number
@Past必须是一个过去的日期
值为null不校验
日期类型
@Future必须是一个将来的日期
值为null不校验
日期类型
@Email必须是电子邮箱地址
值为null不校验
@Length(min=, max=)字符串长度必须在指定的范围内
值为null不校验
String
@Range(min=, max=)数字或字符串数值必须在指定范围内
值为null不校验
String、Number
@URI必须是一个有效的URL字符串
值为null不校验
String

注意:值为null不校验的注解一般和@NotNull一起使用

4、分组校验

  • @Validated通过分组设置不同的校验注解
  • 默认所有注解分组为javax.validation.groups.Default,添加Default,为了没有分组的注解生效
@RestController
public class UserController3 {@PostMapping("/saveUser")public String saveUser(@Validated(value = {User.SaveGroup.class, Default.class}) @RequestBody User user) {System.out.println(user);return "success";}@PostMapping("/updateUser")public String updateUser(@Validated(value = {User.UpdateGroup.class, Default.class}) @RequestBody User user) {System.out.println(user);return "success";}
}
@Data
public class User {// 默认就是Default分组public interface SaveGroup {}public interface UpdateGroup {}// 新增时必须为空@Null(groups = SaveGroup.class)// 修改是必须不为空@NotNull(groups = UpdateGroup.class)private Long id;@NotEmptyprivate String userName;
}

5、自定义校验规则

  • 对于常用的注解的验证规则内容在xxxValidator中,如下

在这里插入图片描述

  • 自定义状态注解,validatedBy则是实现类的Class对象
@Documented
@Constraint(validatedBy = {StatusValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface Status {String message() default "状态标识只能为0或1";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
  • 注解实现类,ConstraintValidator的第一个泛型为自定义注解,第二个为支持类型
public class StatusValidator implements ConstraintValidator<Status, String> {@Overridepublic boolean isValid(String bool, ConstraintValidatorContext constraintValidatorContext) {// 模仿一般的注解,值为null不做校验,和@NotEmpty一起使用if (bool == null) {return true;}// 包含在0和1里面返回true通过,不包含则不通过return Arrays.asList("0","1").contains(bool);}
}

5、校验模式

  • 默认普通模式
    • 校验完所有的属性,然后返回所有的验证失败信息
  • 快速失败返回模式
    • 只要有一个属性校验失败就立马返回

开启快速失败返回模式

@Configuration
public class HibernateValidatorConfiguration {@Beanpublic Validator validator(){ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ).configure()// true  快速失败返回模式    false 普通模式.addProperty( "hibernate.validator.fail_fast", "true" ).buildValidatorFactory();Validator validator = validatorFactory.getValidator();return validator;}
}

6、全局异常处理

  • get和post参数校验抛出异常类型不一样
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseBodypublic ResultEntity<String> handleBindException(Exception ex) {// post请求参数校验if (ex instanceof MethodArgumentNotValidException) {MethodArgumentNotValidException exs = (MethodArgumentNotValidException) ex;FieldError fieldError = exs.getBindingResult().getFieldError();return ResultEntity.fail(400, fieldError.getDefaultMessage(), null);}// get请求参数校验if (ex instanceof ConstraintViolationException) {ConstraintViolationException exs = (ConstraintViolationException) ex;Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();for (ConstraintViolation<?> item : violations) {return ResultEntity.fail(400, item.getMessage(), null);}}return ResultEntity.fail(500, ex.getMessage(), null);}
}@Data
@AllArgsConstructor
@NoArgsConstructor
class ResultEntity<T> {private Integer code;private String message;private T data;public static <T> ResultEntity<T> fail(Integer code, String msg, T t) {return new ResultEntity<T>(code, msg, t);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【从零开始一步步学习VSOA开发】创建VSOA的client端
  • poetry配置镜像
  • 【秋招笔试】2024-08-03-科大讯飞秋招笔试题(算法岗)-三语言题解(CPP/Python/Java)
  • DREAMLLM: SYNERGISTIC MULTIMODALCOMPREHENSION AND CREATION
  • C语言基础题:吃冰棍(C语言版)
  • Android笔试面试题AI答之Activity常见考点
  • AI智能测评应用平台项目分享
  • 数值分析——埃尔米特(Hermit)插值
  • Apple在Swift中引入同态加密
  • Stable Diffusion 官方模型V1.5版本下载
  • LLM - 理解 主流大模型 LLM 使用 Decoder Only 架构 (8点)
  • 回顾前面刷过的算法(4)
  • HanLP和Jieba区别
  • 单元测试JUnit
  • eslint配置忽略目录和文件
  • ➹使用webpack配置多页面应用(MPA)
  • 2017前端实习生面试总结
  • co.js - 让异步代码同步化
  • download使用浅析
  • GraphQL学习过程应该是这样的
  • HTTP请求重发
  • JS+CSS实现数字滚动
  • ubuntu 下nginx安装 并支持https协议
  • Webpack 4 学习01(基础配置)
  • 产品三维模型在线预览
  • 关于 Cirru Editor 存储格式
  • 关于springcloud Gateway中的限流
  • 简单易用的leetcode开发测试工具(npm)
  • 如何学习JavaEE,项目又该如何做?
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 试着探索高并发下的系统架构面貌
  • 通过npm或yarn自动生成vue组件
  • 项目管理碎碎念系列之一:干系人管理
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 移动端唤起键盘时取消position:fixed定位
  • 在electron中实现跨域请求,无需更改服务器端设置
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​数据结构之初始二叉树(3)
  • ## 1.3.Git命令
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #NOIP 2014# day.2 T2 寻找道路
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (11)MSP430F5529 定时器B
  • (CPU/GPU)粒子继承贴图颜色发射
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (zhuan) 一些RL的文献(及笔记)
  • (分布式缓存)Redis持久化
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)linux 命令大全
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .NET技术成长路线架构图
  • .NET开发人员必知的八个网站