Controller 标注 @Validated 开启校验后,使用的自定义校验注解必须要有groups()和payload(),不然就会抛出 ConstraintDefinitionException
@Validated // 标注这个,方法中的 @Min、@Max 和 自定义校验 @ValidExcelFile、@FileSize 等才会生效(Spring 默认不对 @PathVariable 进行校验,需 @Validated 激活)
代码:
/**
* 资金信息控制器
* <p>提供资金信息的增删改查、附件管理、导入导出等 RESTful API。</p>
*/
@RestController
@RequestMapping("/capital/infos")
@Slf4j
@RequiredArgsConstructor
@Validated // 标注这个,方法中的 @Min、@Max 和 自定义校验 @ValidExcelFile、@FileSize 等才会生效(Spring 默认不对 @PathVariable 进行校验,需 @Validated 激活)
public class CapitalInfoController {
private final CapitalInfoService capitalInfoService;
/**
* 导入数据(Excel 文件)
* <p>支持 .xls 和 .xlsx 格式。</p>
*
* @param uploadFile 上传的 Excel 文件
* @param request HttpServletRequest 对象,用于记录请求 URI
* @return 操作结果 {@link Result}<{@link Void}>
*/
@PostMapping("/import")
@Debounce(keyType = Debounce.KeyType.USER, value = 0) // value=0 表示使用配置值
public Result<Void> importData(
@RequestParam("uploadFile")
@NotNull
@ValidExcelFile
@FileSize(max = 1024 * 1024, message = "Excel文件大小不能超过1MB")
MultipartFile uploadFile,
HttpServletRequest request) {
String endpoint = request.getRequestURI();
String method = "importData";
log.info("【资金信息】导入数据,{},{},uploadFile={}", endpoint, method, uploadFile);
capitalInfoService.importData(uploadFile);
return Result.success();
}
}
对自定义注解的要求:要求有 groups() 和 payload() 方法
src/main/java/com/weiyu/annotation/ValidExcelFile.java
package com.weiyu.annotation;
import com.weiyu.validation.ExcelFileValidator;
import jakarta.validation.Constraint;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel文件校验注解
*/
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ExcelFileValidator.class)
public @interface ValidExcelFile {
String message() default "请确保是有效的Excel文件(.xls 或 .xlsx 格式)";
/**
* groups() – 校验分组
* <p>
* - 作用:允许对同一个字段在不同场景下应用不同的校验规则。
* </p>
* <p>
* - 使用场景:例如在新增时 capitalName 字段必须不为空,但更新时允许为空。通过定义分组(如 CreateGroup、UpdateGroup),可以在不同操作时激活不同的校验规则。
* </p>
* <p>
* - 默认行为:如果不指定分组,则属于默认分组 Default.class。
* </p>
*/
Class<?>[] groups() default {};
/**
* payload() – 载荷
* <p>
* - 作用:用于传递附加的元数据,例如错误严重级别(Payload 可以携带自定义信息)。
* </p>
* <p>
* - 使用场景:当校验失败时,可以通过 payload 携带一些额外信息,供上层处理(如国际化、错误分类)。
* </p>
* <p>
* - 实际使用:在大多数项目中并不常用,但规范要求必须存在。通常保持空数组即可。
* </p>
*/
Class<? extends jakarta.validation.Payload>[] payload() default {};
}
当你在 CapitalInfoController 类上添加 @Validated 后,Spring 会启用方法参数校验,从而扫描到所有自定义约束注解(如 @ValidExcelFile、@FileSize、@FileType)。如果这些注解缺少 Bean Validation 规范要求的 groups() 和 payload() 方法,就会抛出 ConstraintDefinitionException。之前由于没有 @Validated 或参数上没有 @Valid,校验未触发,所以问题被隐藏。
错误表明自定义注解 @ValidExcelFile 缺少 Bean Validation 规范要求的 groups() 和 payload() 方法。以下是修正后的注解代码,同时建议检查其他自定义注解(如 @FileSize、@FileType)并补充相同的方法。
修正 @ValidExcelFile
java
package com.weiyu.annotation;
import com.weiyu.validation.ExcelFileValidator;
import jakarta.validation.Constraint;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ExcelFileValidator.class)
public @interface ValidExcelFile {
String message() default "请确保是有效的Excel文件(.xls 或 .xlsx 格式)";
Class<?>[] groups() default {};
Class<? extends jakarta.validation.Payload>[] payload() default {};
}
确保其他自定义注解也符合规范
1. @FileSize(如果未包含)
java
package com.weiyu.annotation;
import com.weiyu.validation.FileSizeValidator;
import jakarta.validation.Constraint;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FileSizeValidator.class)
public @interface FileSize {
String message() default "文件大小不能超过 {max} 字节";
long max() default 10 * 1024 * 1024;
long min() default 0;
Class<?>[] groups() default {};
Class<? extends jakarta.validation.Payload>[] payload() default {};
}
2. @FileType(如果未包含)
java
package com.weiyu.annotation;
import com.weiyu.validation.FileTypeValidator;
import jakarta.validation.Constraint;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FileTypeValidator.class)
public @interface FileType {
String message() default "文件类型不允许";
String[] allowedExtensions() default {};
String[] allowedContentTypes() default {};
String[] excludedExtensions() default {};
String[] excludedContentTypes() default {};
Class<?>[] groups() default {};
Class<? extends jakarta.validation.Payload>[] payload() default {};
}
说明
-
groups()和payload()是 Bean Validation 规范要求的,即使不使用也必须声明,否则会导致ConstraintDefinitionException。 -
所有自定义约束注解都必须包含这两个方法,通常返回空数组即可。
修复后重启应用,错误应消失。
之前没有报错的原因可能是校验未被触发。当你在 CapitalInfoController 类上添加 @Validated 后,Spring 会启用方法参数校验,从而扫描到所有自定义约束注解(如 @ValidExcelFile、@FileSize、@FileType)。如果这些注解缺少 Bean Validation 规范要求的 groups() 和 payload() 方法,就会抛出 ConstraintDefinitionException。之前由于没有 @Validated 或参数上没有 @Valid,校验未触发,所以问题被隐藏。
现在请为所有自定义约束注解补全这两个方法,包括 @ValidExcelFile、@FileSize、@FileType,以及项目中可能存在的其他自定义校验注解。按照上述示例添加即可,错误即可解决。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)