首页/新闻资讯/正文详情

@Validated和@Valid区别

发布时间:2026/11/6 1:11:14 来源:云帆数科 栏目:资讯中心
@Validated和@Valid区别
Validated和Valid区别借鉴文章大佬文章防止文章链接会过期就搬运了基础参数校验 Validated就不过多演示了…分组定义接口 根据接口将不同的校验规则分给不同的组在使用时指定不同的校验规则接口类Group1.Javapackagecom.example.validateddemo.interfaces;/** * 校验分组1 * author He Changjie on 2020/9/5 */publicinterfaceGroup1{}Group2.Javapackagecom.example.validateddemo.interfaces;/** * 校验分组2 * author He Changjie on 2020/9/5 */publicinterfaceGroup2{}实体类使用注解时可以给属性设置多个校验进行分组User2Dto.Javapackagecom.example.validateddemo.entity.dto;importcom.example.validateddemo.interfaces.Group1;importcom.example.validateddemo.interfaces.Group2;importlombok.Data;importjavax.validation.constraints.*;DatapublicclassUser2Dto{/** * 用户名 */NotBlank(message用户名不能为空,groups{Group1.class})//给属性设置组privateStringusername;/** * 性别 */NotBlank(message性别不能为空)privateStringgender;/** * 年龄 */Min(value1,message年龄有误,groups{Group1.class})//设置 Group1Max(value120,message年龄有误,groups{Group2.class})//设置 Group2privateintage;/** * 地址 */NotBlank(message地址不能为空)privateStringaddress;/** * 邮箱 */Email(message邮箱有误,groups{Group2.class})privateStringemail;/** * 手机号码 正则表达式... */Pattern(regexp^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$,message手机号码有误,groups{Group2.class})privateStringmobile;}控制类Controller 中指定了校验的组类型Demo1Controller.Javapackagecom.example.validateddemo.controller;importcom.example.validateddemo.base.Result;importcom.example.validateddemo.entity.dto.Team1Dto;importcom.example.validateddemo.entity.dto.User1Dto;importcom.example.validateddemo.entity.dto.User2Dto;importcom.example.validateddemo.interfaces.Group1;importcom.example.validateddemo.interfaces.Group2;importcom.example.validateddemo.utils.ResultUtil;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;/** * author He Changjie on 2020/9/5 */RestControllerRequestMapping(/api/v1)publicclassDemo1Controller{//不指定分组即是默认组 或 Default.Class 即对没有进行分组的JSR303 数据进行校验PostMapping(/insert3)publicResultvalidatedDemo3(ValidatedRequestBodyUser2Dtouser2Dto){returnResultUtil.success(user2Dto);}PostMapping(/insert4)publicResultvalidatedDemo4(Validated(Group1.class)RequestBodyUser2Dtouser2Dto){returnResultUtil.success(user2Dto);}PostMapping(/insert5)publicResultvalidatedDemo5(Validated(Group2.class)RequestBodyUser2Dtouser2Dto){returnResultUtil.success(user2Dto);}}测试查看insert4使用了Group1 的组校验~查看insert5使用了Group2 的组校验~不指定组使用默认组进行校验则没有进行分组的JSR303 注解生效进行校验通过总结Validated注解可以使用分组进行校验定义分组接口根据接口来给实体类上的校验注解进行分组groups {组接口.class}Controller 上使用时候可以指定校验实体的组不指定即没有组的校验进行校验核对Validated(组接口.class)嵌套验证Valid实体在比较两者嵌套验证时先说明下什么叫做嵌套验证。比如我们现在有个实体叫做ItemItem带有很多属性属性里面有属性id属性值id属性名和属性值如下所示其中包含一个List类型的数据或其它引用类型Item.JavapublicclassItem{NotNull(messageid不能为空)Min(value1,messageid必须为正整数)privateLongid;NotNull(messageprops不能为空)Size(min1,message至少要有一个属性)privateListPropprops;}Prop.JavapublicclassProp{NotNull(messagepid不能为空)Min(value1,messagepid必须为正整数)privateLongpid;NotNull(messagevid不能为空)Min(value1,messagevid必须为正整数)privateLongvid;NotBlank(messagepidName不能为空)privateStringpidName;NotBlank(messagevidName不能为空)privateStringvidName;}Prop属性属性这个实体也有自己的验证机制比如属性和属性值id不能为空属性名和属性值不能为空等控制类ItemController.JavaRestControllerpublicclassItemController{RequestMapping(/item/add)publicvoidaddItem(ValidatedItemitem,BindingResultbindingResult){doSomething();}}程序校验时候如果Item实体的props属性不额外加注释只有NotNull和Size无论入参采用Validated还是Valid验证Spring Validation框架只会对Item的id和props做非空和数量验证不会对props字段里的Prop实体进行字段验证也就是Validated和Valid加在方法参数前都不会自动对参数进行嵌套验证。也就是说如果传的List中有Prop的pid为空或者是负数入参验证不会检测出来。更改实体为了能够进行嵌套验证必须手动在Item实体的props字段上明确指出这个字段里面的实体也要进行验证。由于Validated不能用在成员属性字段上但是Valid能加在成员属性字段上而且Valid类注解上也说明了它支持嵌套验证功能由此推断Valid加在方法参数时并不能够自动进行嵌套验证而是用在需要嵌套验证类的相应字段上来配合方法参数上Validated或Valid来进行嵌套验证Item.JavapublicclassItem{NotNull(messageid不能为空)Min(value1,messageid必须为正整数)privateLongid;Valid// 嵌套验证必须用ValidNotNull(messageprops不能为空)Size(min1,messageprops至少要有一个自定义属性)privateListPropprops;}然后我们在ItemController的addItem函数上再使用Validated或者Valid就能对Item的入参进行嵌套验证。总结嵌套验证就是说注解只能对实体普通属性进行校验如果是引用类型且也是一个对象类型注解并不会自动的进行校验内部的元素Validated和Valid加在方法参数前都不会自动对参数进行嵌套验证由于Validated不能用在成员属性字段上Valid能加在成员属性字段上而且Valid类注解上也说明了它支持嵌套验证功能。所以如果校验需要在实现上对象进行嵌套验证实体内部的对象可以使用Valid对实体属性进行嵌套校验异常处理BindingResultController控制层写参数接收的入口需要注意的是Valid 和 BindingResult 是一 一对应的,如果有多个Valid那么每个Valid后面都需要添加BindingResult用于接收bean中的校验信息.配套使用随意一个ControllerRequestMapping(value/test,methodRequestMethod.POST,producesMediaType.APPLICATION_JSON_VALUE)publicResponseBodyResponseEntityPesponsiblestestBindingResult(ValidRequestBodyParameterparameter,BindingResultbindingResult){log.info(test start);PesponsiblespesponsiblesnewPesponsibles();//判断是否存在,校验异常数据打印日志if(bindingResult.hasErrors()){ListFieldErrorfieldErrorsbindingResult.getFieldErrors();//获取校验异常集合//遍历 输出日志fieldErrors.forEach(fieldError-{//日志打印不符合校验的字段名和错误提示log.error(error field is : {} ,message is : {},fieldError.getField(),fieldError.getDefaultMessage());});//控制台查看for(inti0;ifieldErrors.size();i){//控制台打印不符合校验的字段名和错误提示System.out.println(error field is :fieldErrors.get(i).getField(),message is :fieldErrors.get(i).getDefaultMessage());}//返回前台数据异常这里就根据自己项目情况而定returnnewResponseEntity(pesponsibles,HttpStatus.BAD_REQUEST);}//没有异常操作...returnnewResponseEntity(pesponsibles,HttpStatus.OK);}总结Valid / Validated 要和BindingResult搭配使用用来输出获取校验失败的数据返回前端。如果是使用Spring表单 还可以可以Spring表单进行绑定使用展示异常信息目前少见了根据实际开发需求来做讲异常信息包装返回前端进行展示提示用户全局异常处理类可以先了解此篇文章异常处理因为每个Controller 都会需要进行BindingResult可能会比较麻烦可以使用全局异常进行捕获处理全局处理异常类packagecom.example.validateddemo.handler;importcom.example.validateddemo.base.Result;importcom.example.validateddemo.enums.ResultEnum;importcom.example.validateddemo.utils.ResultUtil;importlombok.extern.slf4j.Slf4j;importorg.springframework.http.HttpStatus;importorg.springframework.validation.BindingResult;importorg.springframework.validation.FieldError;importorg.springframework.validation.ObjectError;importorg.springframework.web.bind.MethodArgumentNotValidException;importorg.springframework.web.bind.annotation.ControllerAdvice;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.ResponseStatus;importjava.util.List;Slf4jControllerAdvicepublicclassValidatedExceptionHandler{/** * 处理Validated参数校验失败异常 * param exception 异常类 * return 响应 */ResponseBody//ResponseStatus的作用就是为了改变HTTP响应的状态码ResponseStatus(HttpStatus.BAD_REQUEST)//改变响应时候 HttpStatus状态 400 接口异常ExceptionHandler(MethodArgumentNotValidException.class)publicResultexceptionHandler(MethodArgumentNotValidExceptionexception){BindingResultresultexception.getBindingResult();StringBuilderstringBuildernewStringBuilder();if(result.hasErrors()){ListObjectErrorerrorsresult.getAllErrors();if(errors!null){errors.forEach(p-{FieldErrorfieldError(FieldError)p;log.warn(Bad Request Parameters: dto entity [{}],field [{}],message [{}],fieldError.getObjectName(),fieldError.getField(),fieldError.getDefaultMessage());stringBuilder.append(fieldError.getDefaultMessage());});}}returnResultUtil.validatedException(stringBuilder.toString());}}ControllerAdvice 注解ControllerAdvice 很多初学者可能都没有听说过这个注解这是一个非常有用的注解顾名思义这是一个增强的 Controller。用这个可以实现三个方面的功能全局异常处理全局数据绑定全局数据预处理 ExceptionHandler 实现全局异常处理!注解声明异常类型, 当类中出现改异常会进入该方法处理在单个Controller中也可以使用但是进限于声明的Controller声明在ControllerAdvice类中则全局的Controller 都会有这个方法任何地方出现异常都会走到这方法中全局异常当将异常抛到controller时,可以对异常进行统一处理:规定返回的json格式或跳转到一个错误页面ControllerAdvicepublicclassMyGlobalExceptionHandler{//注解捕获, Exception类型异常, 即所有的异常都将捕获ExceptionHandler(Exception.class)publicModelAndViewcustomException(Exceptione){ModelAndViewmvnewModelAndView();mv.addObject(message,e.getMessage());mv.setViewName(myerror);returnmv;}}在该类中可以定义多个方法不同的方法处理不同的异常例如专门处理空指针的方法专门处理数组越界的方法…也可以直接向上面代码一样在一个方法中处理所有的异常信息。学习后续扩展总结ControllerAdvice就相当于一个全局的Controller 累下的方法可以被所有的Controller类共享…可以做全局异常初始化数据数据绑定

相关推荐

800VDC固态直流断路器两级选择性保护:125A与1250A配合实战
800VDC固态直流断路器两级选择性保护:125A与1250A配合实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:10:14

智能车竞赛电路设计:稳定电源与电机驱动的关键实现
智能车竞赛电路设计:稳定电源与电机驱动的关键实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:10:14

视频接口(2)—— MIPI Solution
视频接口(2)—— MIPI Solution

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:10:14

Linux:虚拟文件系统/proc和self进程
Linux:虚拟文件系统/proc和self进程

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 目录 /proc目录 self进程 /proc目录 在Linux操作系统中,目录/proc是一个虚拟文件系统,称为procfc,用于访问内核和系统的实时状态信息… · 2026/11/6 1:15:15

10 行代码给噪声 3D 网格做清洗:PyTorch3D 网格预处理笔记
10 行代码给噪声 3D 网格做清洗:PyTorch3D 网格预处理笔记

10 行代码给噪声 3D 网格做清洗:PyTorch3D 网格预处理笔记 【免费下载链接】pytorch3d PyTorch3D is FAIRs library of reusable components for deep learning with 3D data 项目地址: https://gitcode.com/gh_mirrors/py/pytorch3d PyTorch3D 没有内置边折… · 2026/11/6 1:15:15

iloader安装实操:3个平台,从插上iPhone到装好第一个App
iloader安装实操:3个平台,从插上iPhone到装好第一个App

iloader安装实操:3个平台,从插上iPhone到装好第一个App 【免费下载链接】iloader User friendly sideloader 项目地址: https://gitcode.com/GitHub_Trending/iloa/iloader iloader 是一款免费开源的 iOS 侧载工具:不走 App Store,用你自己的 Apple ID 当"开发者账… · 2026/11/6 1:15:15

Jellyfin Desktop 完整指南:从安装到连上媒体库,10 分钟一步到位
Jellyfin Desktop 完整指南:从安装到连上媒体库,10 分钟一步到位

Jellyfin Desktop 完整指南:从安装到连上媒体库,10 分钟一步到位 【免费下载链接】jellyfin-desktop Jellyfin Desktop Client 项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin-desktop 网页端播放器拖个进度条总要等两秒&#xff0c… · 2026/11/6 1:15:15

iloader iOS 侧载指南:点一次按钮装好 SideStore 的完整教程
iloader iOS 侧载指南:点一次按钮装好 SideStore 的完整教程

iloader iOS 侧载指南:点一次按钮装好 SideStore 的完整教程 【免费下载链接】iloader User friendly sideloader 项目地址: https://gitcode.com/GitHub_Trending/iloa/iloader iloader 是一款开源免费的 iOS 侧载(安装 App Store 之外的应用&am… · 2026/11/6 1:15:15

如何批量拿到带时间轴的完整歌词:163MusicLyrics 歌词工具使用指南
如何批量拿到带时间轴的完整歌词:163MusicLyrics 歌词工具使用指南

如何批量拿到带时间轴的完整歌词:163MusicLyrics 歌词工具使用指南 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 给视频配字幕,歌词却只有网页上… · 2026/11/6 1:14:15

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

三菱PLC数据采集到数据库的时序设计:Python+MC协议实战
三菱PLC数据采集到数据库的时序设计:Python+MC协议实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

ASIC主模式RTL设计:状态机与三态驱动的流片级实现
ASIC主模式RTL设计:状态机与三态驱动的流片级实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

STM32嵌入式C++开发:GDB调试与Renode仿真实战指南
STM32嵌入式C++开发:GDB调试与Renode仿真实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码