@Valid不生效的首要原因是未引入spring-boot-starter-validation依赖;其次需确保@Valid修饰参数且紧跟BindingResult,注意@Validated与@Valid在分组和嵌套校验中的差异,自定义注解须匹配泛型类型及Jakarta命名空间。

Spring Boot里@Valid不生效?先检查是否引入了starter
很多人加了@Valid和@NotNull,接口调用却完全不校验——最常见原因是没引入校验依赖。Spring Boot 2.3+ 默认移除了spring-boot-starter-validation的自动依赖,必须手动加。
- Maven里确认有:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> - Gradle对应:
implementation 'org.springframework.boot:spring-boot-starter-validation' - 没有这个依赖,
@Valid只是个空注解,连MethodValidationPostProcessor都不会注册
Controller层校验对象时,@Valid必须写在参数前,且不能漏掉BindingResult
校验失败默认抛MethodArgumentNotValidException,但你想自定义返回格式,就得显式接住错误。关键不是“要不要@Valid”,而是“怎么接住它”。
-
@Valid必须直接修饰方法参数,比如:public ResponseEntity<?> create(@Valid @RequestBody UserDTO user, BindingResult result) -
BindingResult必须紧跟@Valid参数之后,顺序错(比如中间插了个@RequestParam)会导致注入失败 - 如果没写
BindingResult又没全局异常处理器,请求会直接500,日志里只有ConstraintViolationException或MethodArgumentNotValidException
@Validated和@Valid的区别:分组校验和嵌套校验场景下不能混用
单纯非空校验用@Valid够了,但涉及“新增时校验手机号、编辑时校验ID”这类逻辑,就得用@Validated配合分组接口。
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
-
@Validated支持分组:@Validated(User.Create.class),而@Valid不支持 -
@Valid能用在字段上做嵌套校验(比如User类里有个@Valid Address address),@Validated不行 - Controller方法参数只能用
@Validated或@Valid之一,同时写两个不会叠加生效,后者会被忽略
自定义校验注解失效?注意ConstraintValidator的泛型类型必须严格匹配
写了个@Phone注解,实现ConstraintValidator<Phone, String>,但校验始终跳过——大概率是泛型声明和字段类型对不上。
立即学习“Java免费学习笔记(深入)”;
- 如果字段是
private Long phone,ConstraintValidator得写成ConstraintValidator<Phone, Long>,不能写String - 自定义注解类上必须有
@Constraint(validatedBy = PhoneValidator.class) - Spring Boot 3+ 使用Jakarta EE命名空间,注解包名要是
jakarta.validation.constraints,旧的javax.*会静默失效
@Valid List<Item>里的Item想用不同分组,光靠@Validated搞不定,得用@Validated({Default.class, Item.Create.class})再配合@ConvertGroup,这个细节多数人第一次踩坑时根本想不到。









