Springboot参数分组校验
Springboot参数分组校验
文章目录
- Springboot参数分组校验
- 简介
- 代码准备
- 单个或多个参数的校验
- 非 JSON 格式的对象参数校验
- JSON 格式的对象参数校验
- Service 层校验
- 项目地址
简介
Java API
规范(JSR303)定义了Bean校验的标准validation-api
,但没有提供实现。hibernate validation
是对这个规范的实现,并增加了校验注解如@Email
、@Length
等。
Spring Validation
是对hibernate validation
的二次封装,用于支持spring mvc参数自动校验。本文基于 JDK21 和 springboot3.1.5 进行整理。
代码准备
参数校验对象,以下实例都基于该对象进行。
package com.lzhch.practice.dto.req;import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;import java.io.Serial;
import java.io.Serializable;
import java.util.Date;/*** 参数分组校验入参* <p>* author: lzhch* version: v1.0* date: 2023/11/20 15:36*/@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ParamGroupValidatedReq implements Serializable {@Serialprivate static final long serialVersionUID = 1L;/*** 用户ID* 内部定义接口和统一定义接口任选其一即可*/// @NotNull(message = "用户id不能为空", groups = ParamGroupValidated.Create.class)@NotNull(message = "用户id不能为空") // Service 层不进行分组校验// @NotNull(message = "用户id不能为空", groups = ParamGroupValidatedReq.Save.class)private Long userId;/*** 用户名*/@NotBlank(message = "用户名不能为空")@Length(max = 20, message = "用户名不能超过20个字符")private String username;/*** 手机号*/@NotBlank(message = "手机号不能为空")private String mobile;/*** 性别*/private String sex;/*** 邮箱*/@NotBlank(message = "联系邮箱不能为空")@Email(message = "邮箱格式不对")private String email;/*** 密码*/private String password;/*** 创建时间*/// @Future(message = "时间必须是将来时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private Date createTime;/*** 保存的时候校验分组*/public interface Save {}/*** 更新的时候校验分组*/public interface Update {}}
分组接口
import jakarta.validation.groups.Default;/*** 新增参数校验接口* <p>* author: lzhch* version: v1.0* date: 2023/11/20 17:20*/public interface ParamGroupValidated {/*** 在声明分组的时候加上 extend javax.validation.groups.Default* 否则, 在你声明 @Validated(Update.class)的时候, 就会出现你在默认没添加 groups = {} 的时候* 校验组 @Email(message = "邮箱格式不对") 会不去校验, 因为默认的校验组是 groups = {Default.class}.*/interface Create extends Default {}interface Update extends Default {}}
全局异常捕捉,参数校验报错分为 MethodArgumentNotValidException 和 ConstraintViolationException。
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.Objects;/*** 全局异常处理* <p>* author: lzhch* version: v1.0* date: 2023/11/20 17:51*/@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** Controller 层参数校验** @param methodArgumentNotValidException: Controller 层参数校验失败异常类型* @return 统一封装的结果类, 含有代码code和提示信息msg* Author: lzhch 2023/11/21 15:13*/@ExceptionHandler(MethodArgumentNotValidException.class)public String handleMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {log.error(methodArgumentNotValidException.getMessage(), methodArgumentNotValidException);FieldError fieldError = methodArgumentNotValidException.getBindingResult().getFieldError();if (Objects.isNull(fieldError)) {return methodArgumentNotValidException.getMessage();}return fieldError.getDefaultMessage();}/*** 捕获并处理未授权异常** @param e: Service 层参数校验失败异常类型* @return 统一封装的结果类, 含有代码code和提示信息msg* Author: lzhch 2023/11/21 15:13*/@ExceptionHandler(ConstraintViolationException.class)public String handleConstraintViolationException(ConstraintViolationException e) {return String.join(";", e.getConstraintViolations().stream().map(ConstraintViolation::getMessageTemplate).toList());}}
单个或多个参数的校验
比如根据 Id 查询、删除等,无需封装成对象,且无需使用 JSON 格式。
import com.alibaba.fastjson2.JSON;
import com.lzhch.practice.dto.req.ParamGroupValidatedReq;
import com.lzhch.practice.service.IParamGroupValidatedService;
import com.lzhch.practice.validatedtype.ParamGroupValidated;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 参数分组校验 controller* <p>* author: lzhch* version: v1.0* date: 2023/11/20 17:22*/@Slf4j
// 用于在 Controller 层的简单校验, 比如 simple 方法
@Validated
@RestController
@RequestMapping(value = "validated/paramGroup")
public class ParamGroupValidatedController {@Resourceprivate IParamGroupValidatedService paramGroupValidatedService;/*** 简单校验* 必须在 Controller 上添加 @Validated 注解* 指定 groups 可以进行分组校验*/@GetMapping(value = "simple")public void simple(@NotBlank(message = "username 不能是空的啊!!!", groups = ParamGroupValidated.Create.class) String username) {log.info("result {}", username);}}
非 JSON 格式的对象参数校验
Controller 和方法参数上需要添加 @Validated 注解;
对象里面增加相应类型的校验注解。
/*** 非 JSON 格式的对象校验* 使用 @Validated 注解的 value 属性指定分组*/
@GetMapping(value = "simple1")
public void simple1(@Validated ParamGroupValidatedReq paramGroupValidatedReq) {log.info("result {}", JSON.toJSONString(paramGroupValidatedReq));
}
JSON 格式的对象参数校验
不需要在 Controller 上添加 @Validated 注解
JSON 格式校验只需要增加 @RequestBody 注解。
/*** 统一接口分组测试新增* 使用 @Validated 注解的 value 属性指定分组*/
@PostMapping(value = "create")
public void create(@RequestBody @Validated(value = ParamGroupValidated.Create.class) ParamGroupValidatedReq paramGroupValidatedReq) {log.info("result {}", JSON.toJSONString(paramGroupValidatedReq));
}
Service 层校验
以上为在 Controller 里面进行的校验,接下来是 Service 层的校验代码。
接口:
在接口中必须添加 @Valid 以及 @NotBlank 等注解, 否则报错
package com.lzhch.practice.service;import com.lzhch.practice.dto.req.ParamGroupValidatedReq;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;/*** 分组校验接口* <p>* author: lzhch* version: v1.0* date: 2023/11/20 18:16*/public interface IParamGroupValidatedService {// 在接口中必须添加 @Valid 以及 @NotBlank 等注解, 否则报错/*** 字段校验*/void filedValidated(@NotBlank(message = "用户名不能为空") String username);/*** 不分组校验*/void create(@Valid ParamGroupValidatedReq paramGroupValidatedReq);/*** 分组校验*/// @Validated(value = ParamGroupValidated.Create.class)void create1(@Valid ParamGroupValidatedReq paramGroupValidatedReq);}
实现类:
必须给实现类添加 @Validated 注解!
import com.alibaba.fastjson2.JSON;
import com.lzhch.practice.dto.req.ParamGroupValidatedReq;
import com.lzhch.practice.service.IParamGroupValidatedService;
import com.lzhch.practice.validatedtype.ParamGroupValidated;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;/*** 分组校验接口实现类* <p>* author: lzhch* version: v1.0* date: 2023/11/20 18:16*/@Slf4j
@Service
// 在接口上添加 @Validated 注解, 对该类进行参数校验
@Validated
public class ParamGroupValidatedServiceImpl implements IParamGroupValidatedService {/*** 在方法的参数上可以直接使用 @NotBlank 等注解*/@Overridepublic void filedValidated(String username) {log.info("service username :{}", username);}/*** 不分组校验* 在方法上使用 @Valid 注解, 采用默认分组(实体也不指定分组)* 注意:接口中方法参数必须要加 @Valid 注解; 实现类中可加可不加** @param paramGroupValidatedReq param* @return: void* Author: lzhch 2023/11/21 14:56* Since: 1.0.0*/@Overridepublic void create(@Valid ParamGroupValidatedReq paramGroupValidatedReq) {log.info("service result :{}", JSON.toJSONString(paramGroupValidatedReq));}/*** 分组校验* 在不分组校验的基础上对方法添加使用 @Validated 注解, 并指定分组* 注意:接口中方法参数必须要加 @Valid 注解; @Validated 可在接口中也可在实现类中; 不能只在实现类中添加两个注解** @param paramGroupValidatedReq param* @return: void* Author: lzhch 2023/11/21 14:55* Since: 1.0.0*/@Override@Validated(value = ParamGroupValidated.Create.class)public void create1(ParamGroupValidatedReq paramGroupValidatedReq) {log.info("service result :{}", JSON.toJSONString(paramGroupValidatedReq));}}
项目地址
SpringBoot3-Practice/ParamGroupValidated at main · lzhcccccch/SpringBoot3-Practice (github.com)
相关文章:
Springboot参数分组校验
Springboot参数分组校验 文章目录 Springboot参数分组校验简介代码准备单个或多个参数的校验非 JSON 格式的对象参数校验JSON 格式的对象参数校验Service 层校验项目地址 简介 Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现。hibernate …...

无缝集成 MongoDB Relational Migrator,Tapdata 提供关系型到 MongoDB 实时迁移优化方案
在去年的 MongoDB 用户大会纽约站上,MongoDB 正式宣布全面推出新工具 MongoDB Relational Migrator(MongoDB RM),用以简化应用程序迁移和转换——即从传统关系型数据模型到现代的文档数据模型,助力组织快速提升运营效率…...
【C++】每日一题 146 LRU缓存
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 …...
CentOS搭建NAS服务器并使用
CentOS搭建NAS服务器并使用 文章目录 前言一、配置NAS服务器安装 NFS 服务:启动 NFS 服务:使 NFS 服务在系统启动时自动启动: 二、挂载服务器三、常见错误以及解决方案1、mount.nfs: No route to host2、mount.nfs: access denied by server …...

爬虫入门到精通_框架篇16(Scrapy框架基本使用)_名人名言的抓取
1 目标站点分析 抓取网站:http://quotes.toscrape.com/ 主要显示了一些名人名言,以及作者、标签等等信息: 点击next,page变为2: 2 流程框架 抓取第一页:请求第一页的URL并得到源代码,进行下…...
mac inter 芯片遇到程序无法打开(无法验证开发者)
mac inter 芯片遇到程序无法打开(无法验证开发者) 解决方案 终端运行命令: sudo xattr -r -d com.apple.quarantine 文件路径(直接把文件拖入到终端,可以自动找到文件路径)即可令其获得权限 补充知识: 通过gpt可以…...

科技成果鉴定测试如何进行?第三方检测机构进行鉴定测试的好处
科技成果鉴定测试,作为科技领域中一项重要的质量检验手段,具有广泛的应用范围。旨在为科技成果的研发者和使用者提供客观、科学、权威的鉴定结果,从而评估科技成果的技术水平和市场竞争力。 科技成果鉴定测试是对科技成果进行系统、全面的…...

八、词嵌入语言模型(Word Embedding)
词嵌入(Word Embedding, WE),任务是把不可计算、非结构化的词转换为可以计算、结构化的向量,从而便于进行数学处理。 一个更官方一点的定义是:词嵌入是是指把一个维数为所有词的数量的高维空间(one-hot形式…...
重学SpringBoot3-WebMvcConfigurer接口
摘要: 本文详细介绍了SpringBoot 3中的WebMvcConfigurer接口,旨在帮助读者深入理解其原理和实现,从而能够更好地使用SpringBoot进行Web开发。阅读本文需要大约30分钟。 关键词:SpringBoot, WebMvcConfigurer, SpringMVC, Web开发…...

《深入理解springCloud与微服务》笔记
第一章 微服务介绍 1.3 微服务的不足 1.3.2 分布式事务 CAP 理论,即同时满足“一致性”“可用性”和“分区容错”是 件不可能的事。 Consistency :指数据的强一致性。如果写入某个数据成功,之后读取,读到的都是新写入的数据&a…...
Vivado原语模板
1.原语的概念 原语是一种元件! FPGA原语是芯片制造商已经定义好的基本电路元件,是一系列组成逻辑电路的基本单元,FPGA开发者编写逻辑代码时可以调用原语进行底层构建。 2.原语的分类 原语可分为预定义原语和用户自定义原语。预定义原语为如and/or等门级原语不需要例化,可以…...

【linux本地安装tinycudann包教程】
【linux本地安装tinycudann包教程】 tiny-cuda-nn官网链接 如果你是windows 10系统的,想要安装tiny-cuda-nn可以参考我的文章——windows 10安装tiny-cuda-n包 根据官网要求:C++要求对应14,其实这样就已经告诉我们linux系统中的gcc版本不能高于9,同时下面又告诉我们gcc版…...

使用Nginx进行负载均衡
什么是负载均衡 Nginx是一个高性能的开源反向代理服务器,也可以用作负载均衡器。通过Nginx的负载均衡功能,可以将流量分发到多台后端服务器上,实现负载均衡,提高系统的性能、可用性和稳定性。 如下图所示: Nginx负…...

什么护眼台灯效果好?热门护眼台灯全方位测评推荐
台灯可以说是佳佳必备,尤其是家中有正在上学的孩子的更是需要一款好的台灯,不管是看书、写字都离不开台灯。不过很多家长在挑选台灯时往往仅关注到光线亮度是否充足,而忽略掉光线均匀度、舒适度等等方面的问题。所以选择一款优质的护眼台灯是…...

云上三问,迈向智能时代的关键
在今天的中国,第一热词是什么?面对这个问题,“新质生产力”当仁不让,而智能化技术毫无疑问是“新质生产力”最重要的来源之一。 在这样的大势下,大型政企是向新技术要“新质生产力”的时代先锋。云服务,则是…...

【网络安全】手机不幸被远程监控,该如何破解,如何预防?
手机如果不幸被远程监控了,用三招就可以轻松破解,再用三招可以防范于未然。 三招可破解可解除手机被远程监控 1、恢复出厂设置 这一招是手机解决软件故障和系统故障的终极大招。只要点了恢复出厂设置,你手机里后装的各种APP全部将灰飞烟灭…...
每日OJ题_哈希表④_力扣219. 存在重复元素 II
目录 力扣219. 存在重复元素 II 解析代码 力扣219. 存在重复元素 II 219. 存在重复元素 II 难度 简单 给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&am…...

42.坑王驾到第八期:uniCloud报错
uniCloud 报错 今天调用云函数来调试小程序的时候突然暴了一个奇葩错误,require(…).main is not a function。翻官方文档后发现,原来是这样:**如果你写的是云对象,入口文件应为 index.obj.js,如果你写的是云函数入口…...

Linux常用操作命令
Linux常用操作命令 1.文件管理catfile 2.文档编辑3.文件传输4.磁盘管理5.磁盘维护6.网络通讯7.系统管理8.系统设置9.备份压缩10.设备管理 Linux 英文解释为 Linux is not Unix。 Linux内核最初只是由芬兰人李纳斯托瓦兹(Linus Torvalds)在赫尔辛基大学上…...

OpenCV的常用数据类型
OpenCV涉及的常用数据类型除包含C的基本数据类型,如:char、uchar,int、unsigned int,short 、long、float、double等数据类型外, 还包含Vec,Point、Scalar、Size、Rect、RotatedRect、Mat等类。C中的基本数据类型不需再做说明下面重点介绍一下…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...