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

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&#xff0c;但没有提供实现。hibernate …...

无缝集成 MongoDB Relational Migrator,Tapdata 提供关系型到 MongoDB 实时迁移优化方案

在去年的 MongoDB 用户大会纽约站上&#xff0c;MongoDB 正式宣布全面推出新工具 MongoDB Relational Migrator&#xff08;MongoDB RM&#xff09;&#xff0c;用以简化应用程序迁移和转换——即从传统关系型数据模型到现代的文档数据模型&#xff0c;助力组织快速提升运营效率…...

【C++】每日一题 146 LRU缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返回 -1 …...

CentOS搭建NAS服务器并使用

CentOS搭建NAS服务器并使用 文章目录 前言一、配置NAS服务器安装 NFS 服务&#xff1a;启动 NFS 服务&#xff1a;使 NFS 服务在系统启动时自动启动&#xff1a; 二、挂载服务器三、常见错误以及解决方案1、mount.nfs: No route to host2、mount.nfs: access denied by server …...

爬虫入门到精通_框架篇16(Scrapy框架基本使用)_名人名言的抓取

1 目标站点分析 抓取网站&#xff1a;http://quotes.toscrape.com/ 主要显示了一些名人名言&#xff0c;以及作者、标签等等信息&#xff1a; 点击next&#xff0c;page变为2&#xff1a; 2 流程框架 抓取第一页&#xff1a;请求第一页的URL并得到源代码&#xff0c;进行下…...

mac inter 芯片遇到程序无法打开(无法验证开发者)

mac inter 芯片遇到程序无法打开&#xff08;无法验证开发者&#xff09; 解决方案 终端运行命令&#xff1a; sudo xattr -r -d com.apple.quarantine 文件路径(直接把文件拖入到终端&#xff0c;可以自动找到文件路径)即可令其获得权限 补充知识&#xff1a; 通过gpt可以…...

科技成果鉴定测试如何进行?第三方检测机构进行鉴定测试的好处

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

八、词嵌入语言模型(Word Embedding)

词嵌入&#xff08;Word Embedding, WE&#xff09;&#xff0c;任务是把不可计算、非结构化的词转换为可以计算、结构化的向量&#xff0c;从而便于进行数学处理。 一个更官方一点的定义是&#xff1a;词嵌入是是指把一个维数为所有词的数量的高维空间&#xff08;one-hot形式…...

重学SpringBoot3-WebMvcConfigurer接口

摘要&#xff1a; 本文详细介绍了SpringBoot 3中的WebMvcConfigurer接口&#xff0c;旨在帮助读者深入理解其原理和实现&#xff0c;从而能够更好地使用SpringBoot进行Web开发。阅读本文需要大约30分钟。 关键词&#xff1a;SpringBoot, WebMvcConfigurer, SpringMVC, Web开发…...

《深入理解springCloud与微服务》笔记

第一章 微服务介绍 1.3 微服务的不足 1.3.2 分布式事务 CAP 理论&#xff0c;即同时满足“一致性”“可用性”和“分区容错”是 件不可能的事。 Consistency &#xff1a;指数据的强一致性。如果写入某个数据成功&#xff0c;之后读取&#xff0c;读到的都是新写入的数据&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是一个高性能的开源反向代理服务器&#xff0c;也可以用作负载均衡器。通过Nginx的负载均衡功能&#xff0c;可以将流量分发到多台后端服务器上&#xff0c;实现负载均衡&#xff0c;提高系统的性能、可用性和稳定性。 如下图所示&#xff1a; Nginx负…...

什么护眼台灯效果好?热门护眼台灯全方位测评推荐

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

云上三问,迈向智能时代的关键

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

【网络安全】手机不幸被远程监控,该如何破解,如何预防?

手机如果不幸被远程监控了&#xff0c;用三招就可以轻松破解&#xff0c;再用三招可以防范于未然。 三招可破解可解除手机被远程监控 1、恢复出厂设置 这一招是手机解决软件故障和系统故障的终极大招。只要点了恢复出厂设置&#xff0c;你手机里后装的各种APP全部将灰飞烟灭…...

每日OJ题_哈希表④_力扣219. 存在重复元素 II

目录 力扣219. 存在重复元素 II 解析代码 力扣219. 存在重复元素 II 219. 存在重复元素 II 难度 简单 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&am…...

42.坑王驾到第八期:uniCloud报错

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

Linux常用操作命令

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

OpenCV的常用数据类型

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

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...