Hibernate Validator 数据校验框架

news2024/9/29 11:26:12

文章目录

  • 一、数据校验框架简介
    • 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;

    @NotEmpty
    private 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> {
	@Override
	public 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 {
    @Bean
    public 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)
    @ResponseBody
    public 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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1980386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW远程开发

LabVIEW远程开发是指在不同地点的开发者通过网络协同工作&#xff0c;共同开发、调试和维护基于LabVIEW的应用程序。这种开发模式适用于分布式团队、远程办公和全球化项目合作&#xff0c;能够有效利用不同地区的人才和资源。以下是LabVIEW远程开发的详细介绍&#xff1a; 1. 远…

elasticsearch的使用(二)

DSL查询 Elasticsearch的查询可以分为两大类&#xff1a; 叶子查询&#xff08;Leaf query clauses&#xff09;&#xff1a;一般是在特定的字段里查询特定值&#xff0c;属于简单查询&#xff0c;很少单独使用。 复合查询&#xff08;Compound query clauses&#xff09;&am…

C语言程序设计-[4] 算法和程序结构

1、算法 一个程序至少包含两个方面&#xff1a;数据结构和算法&#xff0c;算法就是为解决一个问题而采取的方法和步骤&#xff0c;即对程序操作步骤的描述。 算法有一定的评价标准和表示方法&#xff0c;其中流程图法和N-S结构图法是本章需要介绍的两种方法。 &#xff08;…

校园商铺管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;在线咨询管理&#xff0c;咨询回复管理&#xff0c;交流论坛&#xff0c;系统管理 微信端账号功能包括&a…

LabVIEW工件表面瑕疵识别系统

开发了一种利用LabVIEW和IMAQ Vision视觉工具进行工件表面瑕疵识别的系统。该系统通过图像处理技术识别并分类工件表面的裂纹、划痕等缺陷&#xff0c;从而提升生产线的分拣效率和产品质量。 项目背景 工业生产中&#xff0c;工件表面的缺陷直接影响产品质量和生产效率。传统人…

Web开发-html篇-下

这篇是接着上篇的内容&#xff0c;接着介绍html的其他标签及属性的用法&#xff0c;感兴趣的可以从我的html上篇看起 1. 超链接示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&…

打造干净的Git历史:本地仓库整理操作详解

让你的Git提交如行云流水&#xff1a;本地仓库整理指南 一、背景二、整理上一次提交三、整理多次提交四、注意事项五、总结 一、背景 为什么需要本地仓库整理操作呢&#xff1f; 因为本地仓库提交到远程仓库是无法撤回的&#xff0c;只能是从远端仓库拉取数据到本地&#xff0…

安装ubuntu server24.04系统

0.写在前面 Legacy和UEFI比较legacyUEFI定义基于BIOS的传统引导模式新一代的系统引导模式兼容性较好&#xff0c;支持多数系统主要支持64位系统&#xff0c;对旧版本系统支持较差磁盘分区MBR,最大2.2TB&#xff0c;最多4个主分区GPT&#xff0c;最大16TB&#xff0c;理论上无分…

临床试验设计的干预、受试者和结果指标

临床试验是医学研究中至关重要的一环。通过科学设计和严格实施的临床试验&#xff0c;我们能够系统地评估新药、新疗法以及其他医学干预措施的安全性和有效性。临床试验的设计需考虑多个因素&#xff0c;其中干预、受试者和结局是三大关键要素。本文将详细探讨这些要素在临床试…

基于Jeecgboot3.6.3的vue3版本的流程中仿钉钉流程的鼠标拖动功能支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为原先仿钉钉流程里不能进行鼠标拖动来查看流程&#xff0c;所以根据作者提供的信息进行修改&#xff0c;在hooks下增加下面文件useDraggableScroll.ts import { ref, onMounted, on…

【Python】操作数据库

一、数据库编程接口 为了对数据库进行统一的操作&#xff0c;大多数语言都提供了标准化的数据库接口&#xff08;API&#xff09;。数据库提供了接口&#xff0c;Python定义了规范&#xff08;包括数据操作的对象、函数等&#xff09;&#xff0c;通过Python定义的对象就能直接…

对称加密 和 非对称加密

对称加密 和 非对称加密 文章目录 对称加密 和 非对称加密对称解密——异或运算非对称解密——RSA算法问题RSA算法社会地位缺点 PS&#xff1a;RSA算法的攻击方式 如果对你有帮助&#xff0c;就点赞收藏把&#xff01;(&#xff61;&#xff65;ω&#xff65;&#xff61;)&am…

支持10K长视频理解的多模态大模型MovieChat(CVPR 2024)

MovieChat: From Dense Token to Sparse Memory for Long Video Understanding 论文信息 paper&#xff1a;CVPR 2024 code&#xff1a;https://rese1f.github.io/MovieChat/ 视觉模型大语言模型&#xff1a;首个支持10K帧长视频理解任务的新型框架&#xff08;推荐这篇公众号…

小程序开发全攻略:从零到上线的实战历程

引言 在当今的数字化时代&#xff0c;小程序凭借其轻便、快捷的特点&#xff0c;成为了连接用户与服务的桥梁。作为一名开发者&#xff0c;你可能正考虑踏入小程序开发的领域&#xff0c;但面对纷繁复杂的开发流程和技术要点&#xff0c;或许会感到无从下手。今天&#xff0c;我…

C 语言文件操作详解

目录 引言 一、基本概念 1.什么是文件 2.文件的属性 3.为什么使用文件 4.二进制文件和文本文件 二、文件的打开和关闭 1.流和标准流 2.文件指针 3.文件的打开和关闭 三、⽂件的顺序读写 1.顺序读写函数 2.详细介绍 1.fgetc 2.fputc 3.fgets 4.fputs 5.fscan…

统计:多变量时间序列分析 — VMA、VAR、VARMA

统计&#xff1a;多变量时间序列分析 — VMA、VAR、VARMA 一、说明 多变量时间序列是一个在大学课堂上经常被忽视的话题。然而&#xff0c;真实世界的数据通常具有多个维度&#xff0c;我们需要多变量时间序列分析技术。在这篇博客中&#xff0c;我们将通过可视化和 Python 实现…

【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾

系列篇章&#x1f4a5; No.文章1【GLM-4开发实战】Function Call进阶实战&#xff1a;外部函数调用回顾2【GLM-4开发实战】Function Call进阶实战&#xff1a;常见挑战之意图识别处理3【GLM-4开发实战】Function Call进阶实战&#xff1a;常见挑战之海量函数处理4【GLM-4开发实…

【STM32】GPIO和AFIO标准库使用框架

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 GPIO简介 GPIO时钟使能 GPIO初始化 工作模式 选择引脚 输出速度 函数应用 GPIO初始化框架 8个电平读写函数 写端口电平 读端口电平 GPIO框架汇总 AFIO简介 AFIO时钟使能 函数应…

【Material-UI】深入理解useAutocomplete Hook:自定义与高级用法

文章目录 一、什么是useAutocomplete&#xff1f;导入useAutocomplete 二、基本用法代码解析 三、高级定制1. 自定义选项渲染2. 分组和排序3. 自定义输入框行为4. 与其他组件集成 四、注意事项1. 类型安全2. 性能优化 五、总结 Material-UI提供了强大的Autocomplete组件&#x…

Stable Diffusion绘画 | 图生图-基础使用介绍—重绘幅度与缩放模式

重绘幅度 重绘幅度越大&#xff0c;出图与原图差异越大。 重绘幅度0.7 重绘幅度0.3 缩放模式 目前有以下四种缩放模式&#xff1a; 原图的宽高是1080x1440&#xff0c;当修改宽高&#xff0c;与原图不一致时&#xff0c;可选择其中一种缩放模式来处理图片。 仅调整大小 缩放…