spring内置校验注解无法覆盖车牌号、sql通配符、文件类型大小、身份证校验码、手机号归属地等特殊业务规则,需自定义约束:通过@target、@retention、@constraint绑定校验器,并实现message()、groups()、payload()三个标准属性。

Spring 内置的参数校验注解(如 @NotNull、@Email、@Pattern)覆盖了大部分通用场景,但业务中常有特殊规则——比如校验车牌号、防 SQL 模糊查询通配符(%、_)、限制文件上传类型与大小、校验身份证末位校验码、验证手机号归属地等。这些无法用现成注解表达,必须通过自定义约束扩展。
定义自定义校验注解
新建一个注解类,标注其作用目标(字段或方法参数)、保留策略,并关键地指定校验器实现类:
- 使用
@Target({ElementType.FIELD})表明只能加在字段上(也可加ElementType.PARAMETER支持方法参数) - 使用
@Retention(RetentionPolicy.RUNTIME)确保运行时可通过反射读取 - 必须添加
@Constraint(validatedBy = YourValidator.class),绑定具体校验逻辑 - 声明
message()、groups()、payload()三个标准属性(JSR-303 规范要求)
例如车牌校验注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LicensePlateValidator.class)
public @interface LicensePlate {
String message() default "车牌号格式错误";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
实现 ConstraintValidator 接口
创建校验器类,实现 ConstraintValidator<licenseplate string></licenseplate>,泛型分别对应注解类型和被校验字段类型:
-
initialize():可选,用于初始化正则、缓存或外部资源(如加载省份字典) -
isValid(String value, ConstraintValidatorContext context):核心逻辑,返回true表示通过,false表示失败 - 若需定制错误消息,可通过
context.buildConstraintViolationWithTemplate("自定义提示")覆盖默认 message
注意:方法内应主动处理 null 或空字符串(除非你希望它走 @NotBlank 前置校验)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
在 DTO 中使用并触发校验
将自定义注解加到目标字段上,再配合 @Valid(对象入参)或 @Validated(类/方法级启用)即可生效:
public class CarApplyDTO {
@LicensePlate
private String plateNumber;
@ValidFile(extensions = {"jpg", "png"}, maxSize = 5242880)
private MultipartFile photo;
}
Controller 中写法:
@PostMapping("/apply")
public Result apply(@Valid @RequestBody CarApplyDTO dto) {
// 校验失败时,Spring 会自动抛出 MethodArgumentNotValidException
}
无需手动调用,框架会在数据绑定后、进入方法前自动执行所有约束校验器。
补充:支持分组校验与嵌套校验
若同一字段在不同场景下有不同规则(如新增时必填、编辑时可为空),可结合校验分组:
- 定义空接口作为分组标识,如
public interface Create {}、public interface Update {} - 注解上指定
groups = Create.class - Controller 方法中用
@Validated(Create.class)显式指定分组
对嵌套对象(如 UserDTO 中含 AddressDTO address),只需在 address 字段上加 @Valid,校验会递归穿透下去。










