validation概述spring-boot-starter-validation是 Spring Boot 官方提供的用于数据校验的启动器它基于 Bean Validation API (JSR 380) 标准并默认使用 Hibernate Validator 作为其实现。这个框架能让你通过声明式的注解轻松地对控制器接收的参数、服务层的方法参数以及任何 Java Bean 进行校验确保数据的完整性和有效性。添加依赖dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency常用注解注解适用类型说明示例基础校验NotNull任意类型校验字段值不能为nullNotNull(message ID不能为空)NotEmptyString/Collection/Array/Map校验对象不能为null且长度/大小必须大于 0NotEmpty(message 列表不能为空)NotBlankString校验字符串不能为null且去首尾空格后长度大于 0NotBlank(message 名称不能为空)Null任意类型(新增) 校验字段值必须为nullNull(message 创建时ID必须为空)SizeString/Collection/Array/Map校验长度或大小是否在指定范围内Size(min6, max20, message长度需在6-20之间)数值校验Min/Max数值类型校验数值是否大于等于/小于等于指定值Min(value18, message年龄需大于18)DecimalMin/DecimalMax(新增) BigDecimal/String/数值类似于 Min/Max但支持字符串值适用于高精度数值如金额DecimalMin(value0.01, message金额不能小于0.01)Digits(新增) BigDecimal/数值/String校验数值必须符合指定的整数位和小数位长度Digits(integer5, fraction2, message金额格式错误)Positive(新增) 数值类型校验数值必须为正数 0Positive(message 数量必须为正数)PositiveOrZero(新增) 数值类型校验数值必须为正数或 0 0PositiveOrZero(message 数量不能为负)Negative(新增) 数值类型校验数值必须为负数 0Negative(message 数值必须为负)NegativeOrZero(新增) 数值类型校验数值必须为负数或 0 0NegativeOrZero(message 数值不能为正)逻辑校验AssertTrue(新增) Boolean校验字段值必须为trueAssertTrue(message 必须同意协议)AssertFalse(新增) Boolean校验字段值必须为falseAssertFalse(message 逻辑状态必须为假)日期校验Future/Past日期时间类型校验日期是否在未来/过去Future(message 活动日期必须是未来)FutureOrPresent(新增) 日期时间类型校验日期是否在未来或当前时刻FutureOrPresent(message 日期不能早于现在)PastOrPresent(新增) 日期时间类型校验日期是否在过去或当前时刻PastOrPresent(message 出生日期不能在未来)格式校验EmailString校验是否为有效的邮箱格式Email(message 邮箱格式不正确)PatternString校验字符串是否符合指定的正则表达式Pattern(regexp^1[3-9]\\d{9}$, message手机号格式错误)自定义注解定义注解Target({ElementType.FIELD})Retention(RetentionPolicy.RUNTIME)Constraint(validatedByPhoneValidator.class)// 指定校验器publicinterfacePhone{Stringmessage()default手机号格式不正确;Class?[]groups()default{};Class?extendsPayload[]payload()default{};}实现校验逻辑publicclassPhoneValidatorimplementsConstraintValidatorPhone,String{privatestaticfinalStringPHONE_REGEX^1[3-9]\\d{9}$;OverridepublicbooleanisValid(Stringvalue,ConstraintValidatorContextcontext){returnvalue!nullvalue.matches(PHONE_REGEX);}}使用自定义注解publicclassUserDTO{PhoneprivateStringphoneNumber;}实战开发步骤在DTO中定义校验规则将校验注解直接添加到数据传输对象DTO的字段上并可以通过message属性自定义错误信息。publicclassUserCreateRequest{NotBlank(message用户名不能为空)Size(max50,message用户名长度不能超过50)privateStringname;Email(message邮箱格式不正确)privateStringemail;Min(value18,message年龄必须大于等于18)privateIntegerage;// getters and setters...}在Controller层触发校验在控制器方法的参数前使用Valid或Validated注解即可触发对该参数的校验。RestControllerRequestMapping(/users)publicclassUserController{PostMappingpublicResponseEntityStringcreateUser(RequestBodyValidUserCreateRequestrequest){// 如果校验通过代码会执行到这里returnResponseEntity.ok(用户创建成功);}}Valid与Validated的区别特性Valid(JSR-303/349 标准)Validated(Spring 扩展)分组校验不支持支持方法级校验不支持支持 (需配合Validated在类上)嵌套对象校验支持 (需在字段上使用)支持 (需在字段上使用)统一处理校验异常校验失败会抛出MethodArgumentNotValidException异常。通常使用RestControllerAdvice进行全局统一处理向客户端返回结构化的错误信息。RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(MethodArgumentNotValidException.class)publicResponseEntityMapString,StringhandleValidationException(MethodArgumentNotValidExceptionex){MapString,StringerrorsnewHashMap();// 收集所有字段错误信息ex.getBindingResult().getFieldErrors().forEach(err-errors.put(err.getField(),err.getDefaultMessage()));returnResponseEntity.badRequest().body(errors);}}分组校验分组校验允许你在不同场景下应用不同的校验规则例如创建Create和更新Update操作。定义分组接口publicclassUserGroups{publicinterfaceCreate{}publicinterfaceUpdate{}}在DTO中指定分组publicclassUserDTO{// 创建时ID必须为null更新时ID不能为nullNull(groupsUserGroups.Create.class)NotNull(groupsUserGroups.Update.class)privateLongid;NotBlank(groups{UserGroups.Create.class,UserGroups.Update.class})privateStringusername;// getters and setters...}在Controller中使用指定分组PostMapping(/create)publicStringcreate(RequestBodyValidated(UserGroups.Create.class)UserDTOuser){...}PutMapping(/update)publicStringupdate(RequestBodyValidated(UserGroups.Update.class)UserDTOuser){...}