JSR 303(即 Bean Validation)是一个通过注解在 Java Bean 上定义和执行验证规则的规范
🛠️ 一、JSR 303是什么?
JSR 303(Java Specification Requests 303)是Java EE 6的子规范,全称Bean Validation。它通过注解方式对JavaBean的属性值进行标准化校验,例如检查非空、长度、格式等规则。其参考实现是Hibernate Validator(与Hibernate ORM无关)
核心价值:
✅ 将校验逻辑从业务代码剥离,提升代码可维护性
✅ 统一校验规则,避免重复编码
✅ 支持编译时和运行时校验,增强数据安全性(防止恶意绕过前端校验)
⚙️ 二、快速入门:基础使用
1️⃣ 环境搭建
- Spring Boot项目:添加依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 非Spring项目:需手动引入
validation-api
和hibernate-validator
2️⃣ 常用内置注解
注解 | 适用类型 | 说明 | 示例 |
---|---|---|---|
@NotNull | 任意 | 值不能为null | @NotNull(message="ID不能为空") |
@NotBlank | String | 非null且去除空格后长度>0 | @NotBlank(message="用户名必填") |
@Size | 集合/String | 长度在指定范围内 | @Size(min=6, max=20, message="密码需6-20位") |
@Email | String | 邮箱格式校验 | @Email(message="邮箱格式无效") |
@Pattern | String | 正则表达式匹配 | @Pattern(regexp="^1[3-9]\\d{9}$", message="手机号格式错误") |
@Min /@Max | 数字类型 | 数值范围限制 | @Min(value=18, message="年龄需≥18") |
3️⃣ 在Controller中使用
通过@Valid
或@Validated
触发校验:
@PostMapping("/user")
public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO user) {// 校验通过才执行业务逻辑return ResponseEntity.ok("创建成功");
}
- 校验失败会抛出
MethodArgumentNotValidException
,需全局异常处理
⚡ 三、进阶技巧
1️⃣ 分组校验
解决同一字段在不同场景(如新增/修改)下的差异化校验需求:
// 定义分组接口
public interface AddGroup {}
public interface UpdateGroup {}// 实体类中使用
public class User {@Null(groups = AddGroup.class, message = "新增时ID必须为空")@NotNull(groups = UpdateGroup.class, message = "修改时ID不能为空")private Long id;
}// Controller指定分组
@PostMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody User user) {// ...
}
注:未分组的注解在分组校验中不生效
2️⃣ 自定义校验
步骤:
- 定义注解:
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = ListValueConstraintValidator.class) public @interface ListValue {String message() default "值不在可选范围内";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};int[] vals() default {}; // 允许的值列表,如[0,1] }
- 实现校验器:
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {private Set<Integer> set = new HashSet<>();@Overridepublic void initialize(ListValue constraintAnnotation) {for (int val : constraintAnnotation.vals()) {set.add(val);}}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {return set.contains(value);} }
- 使用自定义注解:
@ListValue(vals = {0, 1}, message = "状态只能是0或1") private Integer status;
💎 四、常见问题
-
Q:
@Valid
vs@Validated
?@Valid
(JSR标准):不支持分组,可嵌套校验字段。@Validated
(Spring扩展):支持分组,不可用于字段
-
Q:校验失败如何获取具体错误?
在Controller参数中添加BindingResult result
,通过result.getFieldErrors()
遍历错误详情 -
Q:为什么int类型推荐用
Integer
?
@Min
等注解在基本类型(如int
)上无法处理空值,而Integer
可兼容null
校验
📚 总结
JSR 303通过声明式注解简化数据校验。初学者可逐步掌握:
1️⃣ 基础注解 → 2️⃣ Controller集成 → 3️⃣ 分组/自定义校验 → 4️⃣ 全局异常处理
结合Spring生态(如Spring MVC)能极大提升开发效率和系统健壮性
更多实践参考:Hibernate Validator文档或Spring官方教程。
相关文章:
JSR 303(即 Bean Validation)是一个通过注解在 Java Bean 上定义和执行验证规则的规范
🛠️ 一、JSR 303是什么? JSR 303(Java Specification Requests 303)是Java EE 6的子规范,全称Bean Validation。它通过注解方式对JavaBean的属性值进行标准化校验,例如检查非空、长度、格式等规则…...
5G 网络中的双向认证机制解析
一、5G 网络中的双向认证机制解析 在 5G 核心网中,双向认证是指UE(用户设备)与网络互相验证对方身份的过程。这一机制通过多层次的安全协议和密钥交换,确保通信双方的合法性,防止中间人攻击和身份伪造。 1. UE 存储的关键信息 UE 作为用户终端,存储以下核心安全信息:…...
DAY07:Vue Router深度解析与多页面博客系统实战
第一部分:Vue Router核心概念深度剖析 1.1 现代前端路由的本质 在单页应用(SPA)时代,前端路由扮演着至关重要的角色。它突破了传统多页面应用的跳转方式,通过以下机制实现无刷新页面切换: Hash模式&#…...

Drawio编辑器二次开发
Drawio (现更名为 Diagrams.net )是一款完全免费的在线图表绘制工具,由 JGraph公司 开发。它支持创建多种类型的图表,包括流程图、组织结构图、UML图、网络拓扑图、思维导图等,适用于商务演示、软件设计等多种场景…...

1.测试过程之需求分析和测试计划
测试基础 流程 1.分析测试需求 2.编写测试计划 3.设计与编写测试用例 4.执行测试 5.评估与总结 测试目标 根据测试阶段不同可分为四个主要目标:预防错误(早期)、发现错误(开发阶段)、建立信心(验收阶段&a…...
第三十七天打卡
过拟合的判断:测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint,还包含训练状态 早停策略 过拟合判断 import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load…...
Qt 窗口标志(Window Flags)详解:控制窗口样式与行为
在 Qt 中,windowFlags 用于控制窗口的样式和行为,包括标题栏、边框、最大化/最小化按钮等。合理设置 windowFlags 可以自定义窗口的外观和交互方式。本文将详细介绍常用的窗口标志及其组合效果。 1. 基本概念 windowFlags 是一个 Qt::WindowFlags 类型的…...
ABP VNext + CRDT 打造实时协同编辑
🛠️ ABP VNext CRDT 打造实时协同编辑器 🎉 📚 目录 🛠️ ABP VNext CRDT 打造实时协同编辑器 🎉🧠 背景与挑战🔹 系统架构🛣️ 端到端流程 🚦🔒 安全与鉴…...
微信小程序真机调试时如何实现与本地开发环境服务器交互
最近在开发微信小程序项目,真机调试时需要在手机上运行小程序,为了实现本地开发服务器与手机小程序的交互,需要以下步骤 1.将手机连到和本地一样的局域网 2.Visual Studio中将IIS Express服务器的localhost端口地址修改为本机的IP自定义的端口: 1)找到web api项目…...
Linux: network: dpdk, VF, ip link set down 对VF不生效
文章目录 问题另一个测试的结果是从dpdk的文档看怎么设置VF给VM内核的调用需要使用的命令问题 最近遇到一个问题,也可以说是一种常识,至少是之前不知道的常识:如果一个VF分配给了VM用作dpdk的输入。在host做ip link set down 这个PF的接口,对这个VM里的VF的功能没有任何影…...

[春秋云镜] CVE-2023-23752 writeup
首先奉上大佬的wp表示尊敬:(很详细)[ 漏洞复现篇 ] Joomla未授权访问Rest API漏洞(CVE-2023-23752)_joomla未授权访问漏洞(cve-2023-23752)-CSDN博客 知识点 Joomla版本为4.0.0 到 4.2.7 存在未授权访问漏洞 Joomla是一套全球知名的内容管理…...
Java集合操作常见错误与最佳实践
错误69:搜索无关类型的对象 泛型方法的类型安全漏洞 在Java引入参数化类型前,集合元素只能声明为Object类型,导致可以随意将字符串添加到数值列表中。虽然泛型机制对添加元素的方法进行了类型约束,但搜索和删除相关方法仍保留了Object类型的参数设计。这包括以下关键方法…...

CSS专题之水平垂直居中
前言 石匠敲击石头的第 16 次 在日常开发中,经常会遇到水平垂直居中的布局,虽然现在基本上都用 Flex 可以轻松实现,但是在某些无法使用 Flex 的情况下,又应该如何让元素水平垂直居中呢?这也是一道面试的必考题…...
python打卡day41@浙大疏锦行
知识回顾 1. 数据增强 2. 卷积神经网络定义的写法 3. batch归一化:调整一个批次的分布,常用与图像数据 4. 特征图:只有卷积操作输出的才叫特征图 5. 调度器:直接修改基础学习率 卷积操作常见流程如下: 1. …...
vue3 基本语法 父子关系
在Vue 3中,父子组件的关系是通过组件的嵌套实现的。父组件可以传递数据(props)给子组件,同时子组件可以通过事件(emits)与父组件通信。下面是如何在Vue 3中建立和使用父子组件的基本语法: 1. 创…...
算法-js-子集
题:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 方法一:迭代法 核心逻辑:动态扩展子集, 小规…...

(新)MQ高级-MQ的可靠性
消息到达MQ以后,如果MQ不能及时保存,也会导致消息丢失,所以MQ的可靠性也非常重要。 一、数据持久化 为了提升性能,默认情况下MQ的数据都是在内存存储的临时数据,重启后就会消失。为了保证数据的可靠性,必须…...
Android设置界面层级为最上层实现
Android设置界面层级为最上层实现 文章目录 Android设置界面层级为最上层实现一、前言二、Android设置界面层级为最上层实现1、主要代码2、后遗症 三、其他1、Android设置界面层级为最上层小结2、悬浮框的主要代码悬浮框 注意事项(1)权限限制(…...
云原生微服务架构演进之路:理念、挑战与实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:架构的演进是业务进化的技术反射 在软件行业的发展过程中,架构变迁总是伴随着技术浪潮与业务复杂度的升…...
Go语言使用阿里云模版短信服务
在当今的互联网项目中,短信验证码、通知等功能已成为标配。本文将详细介绍如何使用Go语言集成阿里云短信服务(DYSMSAPI)实现短信发送功能。 一、准备工作 在开始之前,您需要完成以下准备工作: 注册阿里云账号并实名认证开通短信服务(SMS)申…...

Leetcode 3231. 要删除的递增子序列的最小数量
1.题目基本信息 1.1.题目描述 给定一个整数数组 nums,你可以执行任意次下面的操作: 从数组删除一个 严格递增 的 子序列。 您的任务是找到使数组为 空 所需的 最小 操作数。 1.2.题目地址 https://leetcode.cn/problems/minimum-number-of-increas…...

4.2.5 Spark SQL 分区自动推断
在本节实战中,我们学习了Spark SQL的分区自动推断功能,这是一种提升查询性能的有效手段。通过创建具有不同分区的目录结构,并在这些目录中放置JSON文件,我们模拟了一个分区表的环境。使用Spark SQL读取这些数据时,Spar…...
基于昇腾MindSpeed训练加速库玩转智谱GLM-4-0414模型
智谱GLM-4-0414模型提供32B和9B两种参数规模,涵盖基础、推理和沉思等多种模型类型,均基于 MIT 许可协议开放。其中,推理模型 GLM-Z1-32B-0414 性能卓越,与 DeepSeek-R1 等领先模型相当,实测推理速度达每秒200个Tokens。…...

【图像处理入门】2. Python中OpenCV与Matplotlib的图像操作指南
一、环境准备 import cv2 import numpy as np import matplotlib.pyplot as plt# 配置中文字体显示(可选) plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False二、图像的基本操作 1. 图像读取、显示与保存 使用OpenCV…...

Spring Boot微服务架构(九):设计哲学是什么?
一、Spring Boot设计哲学是什么? Spring Boot 的设计哲学可以概括为 “约定优于配置” 和 “开箱即用”,其核心目标是极大地简化基于 Spring 框架的生产级应用的初始搭建和开发过程,让开发者能够快速启动并运行项目…...
GRCh38版本染色体位置转换GRCh37(hg19)
目录 方法 1:使用 Ensembl REST API(推荐,适用于少量位点查询)方法 2:使用 UCSC API方法 3:使用 NCBI API 并转换坐标(需要额外步骤)方法 4:使用本地数据库(最…...

TC/BC/OC P2P/E2E有啥区别?-PTP协议基础概念介绍
前言 时间同步网络中的每个节点,都被称为时钟,PTP协议定义了三种基本时钟节点。本文将介绍这三种类型的时钟,以及gPTP在同步机制上与其他机制的区别 本系列文章将由浅入深的带你了解gPTP,欢迎关注 时钟类型 在PTP中我们将各节…...
解决微信小程序中 Flex 布局下 margin-right 不生效的问题
解决微信小程序中 Flex 布局下 margin-right 不生效的问题 在做微信小程序开发时,遇到了一个棘手的布局问题:在 flex 布局下,给元素设置的 margin-right 不生效,被“吞噬”了。这个问题导致了横向滚动列表的右边距失效࿰…...

Kafka数据怎么保障不丢失
在分布式消息系统中,数据不丢失是核心可靠性需求之一。Apache Kafka 通过生产者配置、副本机制、持久化策略、消费者偏移量管理等多层机制保障数据可靠性。以下从不同维度解析 Kafka 数据不丢失的核心策略,并附示意图辅助理解。 一、生产者端:…...
使用HTTPS进行传输加密
说明 日期:2025年5月30日 与以纯文本形式发送和接收消息的标准 HTTP 不同,HTTPS 使用SSL/TLS等协议对服务器进行身份验证、加密通信内容和检测篡改。 这样可以防止欺骗、中间人攻击和窃听等攻击。 证书很重要,如果用户主动信任了伪造证书&…...