【Spring Boot】Web开发 — 数据验证
Web开发 — 数据验证
对于应用系统而言,任何客户端传入的数据都不是绝对安全有效的,这就要求我们在服务端接收到数据时也对数据的有效性进行验证,以确保传入的数据安全正确。接下来介绍Spring Boot是如何实现数据验证的。
1.Hibernate Validator简介
数据校验是Web开发中的重要部分,目前数据校验的规范、组件非常多,有JSR-303/JSR-349、Hibernate Validator、Spring Validation。
- JSR(Java Specification Request)规范是Java EE 6中的一项子规范,也叫作Bean Validation。它指定了一整套基于bean的验证API,通过标注给对象属性添加约束条件。
- Hibernate Validator是对JSR规范的实现,并增加了一些其他校验注解,如@Email、@Length、@Range等。
- Spring Validation是Spring为了给开发者提供便捷,对Hibernate Validator进行了二次封装。同时,Spring Validation在SpringMVC模块中添加了自动校验,并将校验信息封装进了特定的类中。
JSR定义了数据验证规范,而Hibernate Validator则是基于JSR规范,实现了各种数据验证的注解以及一些附加的约束注解。Spring Validation则是对Hibernate Validator的封装整合。JSR和Hibernate Validator中的常用注解如表所示。
表中包含了Hibernate Validator实现的JSR-303定义的验证注解和Hibernate Validator自己定义的验证注解,同时也支持自定义约束注解。所有的注解都包含code和message这两个属性。
- Message定义数据校验不通过时的错误提示信息。
- code定义错误的类型。
Spring Boot是从Spring发展而来的,所以自然支持Hibernate Validator和Spring Validation两种方式,默认使用的是Hibernate Validator组件。
2.数据校验
使用Hibernate Validator校验数据需要定义一个接收的数据模型,使用注解的形式描述字段校验的规则。下面以User对象为例演示如何使用Hibernate Validator校验数据。
2.1 JavaBean参数校验
Post请求参数较多时,可以在对应的数据模型(Java Bean)中进行数据校验,通过注解来指定字段校验的规则。下面以具体的实例来进行演示。首先,创建Java Bean实体类:
public class User {@NotBlank(message = "姓名不允许为空!")@Length(min = 2, max = 1,message = "姓名长度错误,姓名长度2-10!")private String name;@NotNull(message ="年龄不能为空!")@Min(18)private int age;@NotBlank(message ="地址不能为空!")private String address;@Pattern(regexp = "((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")private String phone;@Email(message ="邮箱格式错误")private String email;//省略get和set方法
}
在示例中,每个注解中的属性message是数据校验不通过时要给出的提示信息,如@Email(message=“邮件格式错误”),当邮件格式校验不通过时,提示邮件格式错误。然后,添加数据校验方法:
@PostMapping(path ="/check")public String check(@RequestBody @Valid User user, BindingResult result) {String name = user.getName();if(result.hasErrors()) {List<ObjectError> list = result.getAllErrors();for (ObjectError error : list) {System.out.println(error.getCode() + "_" + error.getDefaultMessage());}}return name;}
在上面的示例中,在@RequestBody注解后面添加了@Valid注解,然后在后面添加了BindingResult返回验证结果,BindingResult是验证不通过时的结果集合。
注意,BindingResult必须跟在被校验参数之后,若被校验参数之后没有BindingResult对象,则会抛出BindException。
最后,运行验证。
启动项目,在postman中请求/user/check接口,后台输出了数据验证的结果:
Length-密码长度错误,密码长度6-20!
Min-最小不能小于18
Length-姓名长度错误,姓名长度2-10!
通过上面的输出可以看到,应用系统对传入的数据进行了校验,同时也返回了对应的数据校验结果。
2.2 URL参数校验
一般GET请求都是在URL中传入参数。对于这种情况,可以直接通过注解来指定参数的校验规则。下面通过实例进行演示。
@Validated
public class UserController {@RequestMapping("/query")public String query(@Length(min = 2, max = 1, message ="姓名长度错误,姓名长度2-10!")@RequestParam(name = "name", required = true) String name,@Min(value = 1, message = "年龄最小只能1")@Max(value = 99, message = "年龄最大只能9")@RequestParam(name = "age", required = true) int age) {System.out.println(name + " , " + age);return name + " , " + age;}
}
在上面的示例中,使用@Range、@Min、@Max等注解对URL中传入的参数进行校验。需要注意的是,使用@Valid注解是无效的,需要在方法所在的控制器上添加@Validated注解来使得验证生效。
2.3 JavaBean对象级联校验
对于JavaBean对象中的普通属性字段,我们可以直接使用注解进行数据校验,那如果是关联对象呢?其实也很简单,在属性上添加@Valid注解就可以作为属性对象的内部属性进行验证(验证User对象,可以验证UserDetail的字段)。示例代码如下:
public class User {@Size(min = 3, max = 5, message = "list的Size在[3,5]")private List<String> list;@NotNull@Validprivate Demo3 demo3;
}public class UserDetail {@Length(min = 5,max = 17,message = "length长度在[5,17]之间")private String extField;
}
在上面的示例中,在属性上添加@Valid就可以对User中的关联对象UserDetail的字段进行数据校验。
2.4 分组校验
在不同情况下,可能对JavaBean对象的数据校验规则有所不同,有时需要根据数据状态对JavaBean中的某些属性字段进行单独验证。这时就可以使用分组校验功能,即根据状态启用一组约束。Hibernate Validator的注解提供了groups参数,用于指定分组,如果没有指定groups参数,则默认属于javax.validation.groups.Default分组。
下面通过示例演示分组校验。首先,创建分组GroupA和GroupB,示例代码如下:
public interface GroupA {
}
public interface GroupB {
}
在上面的示例中,我们定义了GroupA和GroupB两个接口作为两个校验规则的分组。然后,创建实体类Person,并在相关的字段中定义校验分组规则,示例代码如下:
public class User {@NotBlank(message ="userId不能为空",groups = {GroupA.class})
/**用户id*/private Integer userId;@NotBlank(message ="用户名不能为空",groups = {GroupA.class})/**用户id*/private String name;@Length(min = 30,max = 40,message = "必须在[30,40]",groups = {GroupB.class})@Length(min = 20,max = 30,message = "必须在[20,30]",groups = {GroupA.class})/**用户名*/private int age;
}
在上面的示例中,userName字段定义了GroupA和GroupB两个分组校验规则。GroupA的校验规则为年龄在20~30,GroupB的校验规则为年龄在30~40。最后,使用校验分组:
@RequestMapping("/save")
public String save(@RequestBody @Validated({GroupA.class, Default.class}) Person person, BindingResult result) {System.out.println(JSON.toJSONString(result.getAllErrors()));
return "success";
在上面的示例中,在@Validated注解中增加了{GroupA.class,Default.class}参数,表示对于定义了分组校验的字段使用GroupA校验规则,其他字段使用默认规则。
3.自定义校验
Hibernate Validator支持自定义校验规则。通过自定义校验规则,可以实现一些复杂、特殊的数据验证功能。下面通过示例演示如何创建和使用自定义验证规则。
3.1 声明一个自定义校验注解
首先,定义新的校验注解@CustomAgeValidator,示例代码如下:
@Min(value = 18, message ="年龄最小不能小于18")@Max(value = 120, message ="年龄最大不能超过120")@Constraint(validatedBy = {}) //不指定校验器@Documented@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface CustomAgeValidator {String message() default "年龄大小必须大于18并且小于123";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}
在上面的示例中,我们创建了CustomAgeValidator自定义注解,用于自定义年龄的数据校验规则。
3.2 使用自定义校验注解
创建自定义校验注解CustomAgeValidator之后,在User的age属性上使用自定义组合注解,示例代码如下:
@public class User {@NotBlank(message ="姓名不允许为空!")@Length(min = 2,max = 10,message ="姓名长度错误,姓名长度2-10!")private String name;@CustomAgeValidatorprivate int age;@NotBlank(message ="地址不能为空!")private String address;@Pattern(regexp = "((13[-9])|(14[5,7,9])|(15([-3]][5-9]))|(166)(17[.1,3,5,6,7,8])l(18[0-9])I(19[8|9]))\\d{8}$", message ="手机号格式错误")private String phone;@Email(message ="邮箱格式错误")private String email;//省略get和set
}
在上面的示例中,我们在需要做特殊校验的age字段上添加@CustomAgeValidator自定义注解,这样age字段就会使用我们自定义的校验规则。
相关文章:

【Spring Boot】Web开发 — 数据验证
Web开发 — 数据验证 对于应用系统而言,任何客户端传入的数据都不是绝对安全有效的,这就要求我们在服务端接收到数据时也对数据的有效性进行验证,以确保传入的数据安全正确。接下来介绍Spring Boot是如何实现数据验证的。 1.Hibernate Vali…...

技术分享 | App常见bug解析
功能Bug 内容显示错误 前端页面展示的内容有误。 这种错误的产生有两种可能 1、前端代码写的文案错误 2、接口返回值错误 功能错误 功能错误是在测试过程中最常见的类型之一,也就是产品的功能没有实现。比如图中的公众号登录不成功的问题。 界面展示错乱 产…...
树莓派Pico|RP2040|使用SWD进行调试|构建 “Hello World“ debug版本
文章目录 使用SWD进行调试构建 "Hello World" debug版本安装 GDB使用 GDB 和 OpenOCD 来 debug Hello World TIP重要提示 使用SWD进行调试 基于rp2040的板上的SWD端口重置,加载和运行代码,如树莓派Pico可用于交互式调试已加载的程序。这包括:…...

Ubuntu18.04 下配置Clion
配置Clion 安装gcc、g、make Ubuntu中用到的编译工具是gcc©,g(C),make(连接)。因此只需安装对应的工具包即可。Ubuntu下使用命令安装这些包: (1)安装gcc sudo apt install gcc&am…...

数据库管理-第九十四期 19c OCM之路-第四堂(02)(20230725)
第九十四期 19c OCM之路-第四堂(02)(20230725) 第四堂继续! 考点3:SQL statement tuning SQL语句调优 收集Schema统计信息 exec dbms_stats.gather_schems_stats(HR);开启制定表索引监控 create index…...

以智慧监测模式守护燃气安全 ,汉威科技“传感芯”凸显智慧力
城市燃气工程作为城市基建的重要组成部分,与城市居民生活、工业生产紧密相关。提升城市燃气服务质量和安全水平,也一直是政府和民众关注的大事。然而,近年来居民住宅、餐饮等工商业场所燃气事故频发,时刻敲响的警钟也折射出我国在…...

【阅读笔记】一种暗通道优先的快速自动白平衡算法
解决问题: 自动白平衡算法中存在白色区域检测错误导致白平衡失效的问题,作者提出了一种基于暗通道优先的白平衡算法。 算法思想: 图像中白色区域或者高饱和度区域的光线透射率较低,根据以上特性利用暗通道法计算图像中白色区域。 算法概述: 作者使用何凯明提出的基于暗…...
OpenStack之云主机管理
一)必备知识 1.云主机与快照管理 a-云主机管理 云主机管理是OpenStack云计算平台的核心功能,通常,云主机的管理包括创建、删除、查询等。可使用以下命令对OpenStack的云主机进行管理: openstack server <操作><云主机…...

Linux系列---【Ubuntu 20.04安装KVM】
Ubuntu 20.04安装KVM 一、安装kvm 1.安装kvm sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils 2. 将当前用户添加至libvirt 、 kvm组 sudo adduser $USER libvirt sudo adduser $USER kvm 3.验证安装 virsh list --all 4.启动libvert sudo syst…...

【Vue3】局部组件和全局组件
1. 局部组件 Card.vue <template><div class"card"><header><div>标题</div><div>副标题</div></header><section>内容</section></div> </template><script setup lang"ts"…...
vscode开发Go和Java
vscode开发Go和Java 最新最全 vscode 插件推荐可以参考: https://zhuanlan.zhihu.com/p/623580867 1、公共插件安装 下面是个人使用的插件: # 中文插件 Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code https://marketplace…...

自定义MVC
目录 一.什么是MVC 1.1.三层架构和MVC的区别 二.自定义MVC工作原理图 三.自定义mvc实现 3.1 创建web工程 3.2 中央处理器 3.3 Action接口定义 3.4 实现子控制器 3.5 完善中央控制器 3.5.1 请求分发功能 3.5.2 使用配置文件配置action 3.5.3 请求参数处理 1. 定义接…...

简单分享婚宴预订小程序怎么做
婚宴预订小程序需要具备一些功能,通过这些功能,新人可以更方便地选择婚宴场地、预订服务,并且更好地规划自己的婚礼。 1. 场地浏览与选择 婚宴预订小程序可以展示多个婚宴场地的照片和详细信息,包括容纳人数、场地设施、价格等。…...

【多模态】19、RegionCLIP | 基于 Region 来实现视觉语言模型预训练
文章目录 一、背景二、方法2.1 Region-based Language-Image Pretraining2.2 目标检测的迁移学习 三、效果3.1 数据集3.2 实现细节3.3 结果 论文: RegionCLIP: Region-based Language-Image Pretraining 代码:https://github.com/microsoft/RegionCLIP …...

本地文件夹上传到Github
本地文件夹上传到Github 步骤1. 下载git步骤2. 在github中新建一个库(Repository)步骤3. 设置SSH key步骤4. 添加SSH keys步骤5. 本地文件上传到github参考 步骤1. 下载git 下载git客户端,并在本地安装完成。 步骤2. 在github中新建一个库&a…...

云原生|kubernetes|kubernetes集群部署神器kubekey安装部署高可用k8s集群(半离线形式)
前言: 云原生|kubernetes|kubernetes集群部署神器kubekey的初步使用(centos7下的kubekey使用)_晚风_END的博客-CSDN博客 前面利用kubekey部署了一个简单的非高可用,etcd单实例的kubernetes集群,经过研究,…...

Vite + Vue3 +TS 项目router配置踩坑记录! ===>“找不到模块“vue-router”或其相应的类型声明。“<===
目录 第一个坑:"找不到模块“vue-router”或其相应的类型声明。" 解决 第二个坑:Cannot read properties of undefined (reading push) 解决:将useRouter()方法的执行位置尽量放靠上一点就行了。 最近在使用vite vue3 types…...

windows安装npm, 命令简介
安装步骤 要在Windows上安装npm,按照以下步骤操作: 首先,确保您已经在计算机上安装了Node.js。可以从Node.js官方网站(Node.js)下载并安装Node.js。完成Node.js的安装后,打开命令提示符(Command…...

微信聊天记录监管有多重要?
在现代企业中,微信成为了主流的沟通工具。越来越多企业开始关注员工聊天记录的监管问题,因为这直接关系到信息泄露的风险。监管员工聊天记录可以保障公司形象、保护员工的安全,并有助于提高员工的工作效率。 监管员工聊天记录到底有多重要&am…...

【数据结构】实验十:哈夫曼编码
实验十 哈夫曼编码 一、实验目的与要求 1)掌握树、森林与二叉树的转换; 2)掌握哈夫曼树和哈夫曼编码算法的实现; 二、 实验内容 1. 请编程实现如图所示的树转化为二叉树。 2. 编程实现一个哈夫曼编码系统,系统功能…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...