网站建设案例 星座英文网站 常用字体
网站建设案例 星座,英文网站 常用字体,新品发布会ppt,电商营业执照9 个 Spring Boot 参数验证高阶技巧#xff08;2025–2026 实战版#xff09;
Spring Boot 的参数验证#xff08;Bean Validation Hibernate Validator#xff09;早已不是简单的 NotNull、Size#xff0c;下面这些高阶用法可以让你的代码更简洁、更统一、更易维护Class?[]groups()default{};Class?extendsPayload[]payload()default{};}publicclassPhoneNumberValidatorimplementsConstraintValidatorPhoneNumber,String{privatestaticfinalPatternPATTERNPattern.compile(^1[3-9]\\d{9}$);OverridepublicbooleanisValid(Stringvalue,ConstraintValidatorContextcontext){returnvalue!nullPATTERN.matcher(value).matches();}}使用PostMapping(/register)publicResponseregister(RequestBodyValidatedRegisterDTOdto){// ...}publicclassRegisterDTO{PhoneNumberprivateStringphone;}2. Valid Validated 的正确组合使用Valid用于对象字段嵌套校验JSR-303 标准ValidatedSpring 增强版支持分组校验、类级别校验publicclassOrderCreateDTO{NotNullprivateLonguserId;Valid// 嵌套校验privateListOrderItemDTOitems;}PostMapping(/orders)publicvoidcreate(RequestBodyValidated(Group.Create.class)OrderCreateDTOdto){// ...}3. 分组校验Group Validation——同一个 DTO 不同场景不同规则publicinterfaceCreate{}publicinterfaceUpdate{}publicclassUserDTO{Null(groupsCreate.class)// 创建时 id 必须为空NotNull(groupsUpdate.class)// 更新时 id 必须有privateLongid;NotBlank(groups{Create.class,Update.class})privateStringusername;}PostMapping(/users)publicvoidcreate(Validated(Create.class)UserDTOdto){...}PutMapping(/users/{id})publicvoidupdate(Validated(Update.class)UserDTOdto){...}4. 类级别校验Class-level validation校验整个对象而非单个字段。ScriptAssert(langjavascript,script_this.startDate.before(_this.endDate),message结束时间不能早于开始时间)publicclassActivityDTO{privateLocalDatestartDate;privateLocalDateendDate;}或者更推荐自定义 ConstraintTarget({ElementType.TYPE})Retention(RetentionPolicy.RUNTIME)Constraint(validatedByDateRangeValidator.class)publicinterfaceDateRange{Stringmessage()default结束时间不能早于开始时间;// ...}5. JsonView 校验分组联动结合JsonView和分组校验实现“不同接口不同字段 不同校验规则”。publicinterfaceViews{interfaceCreate{};interfaceUpdate{};}publicclassUserDTO{Null(groupsViews.Create.class)NotNull(groupsViews.Update.class)JsonView({Views.Create.class,Views.Update.class})privateLongid;}6. MethodValidationPostProcessor 开启方法参数/返回值校验ConfigurationpublicclassValidationConfig{BeanpublicMethodValidationPostProcessormethodValidationPostProcessor(){MethodValidationPostProcessorprocessornewMethodValidationPostProcessor();processor.setValidator(Validation.buildDefaultValidatorFactory().getValidator());returnprocessor;}}然后在 Controller/Service 直接用ValidatedRestControllerpublicclassUserController{PostMapping(/users)publicUsercreateUser(ValidRequestBodyUserDTOdto){// ...}}7. 自定义全局异常处理器 统一错误响应RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(ConstraintViolationException.class)ResponseStatus(HttpStatus.BAD_REQUEST)publicRhandleConstraintViolation(ConstraintViolationExceptione){ListStringerrorse.getConstraintViolations().stream().map(v-v.getMessage()).toList();returnR.error(400,参数校验失败,errors);}ExceptionHandler(MethodArgumentNotValidException.class)publicRhandleMethodArgumentNotValid(MethodArgumentNotValidExceptione){ListStringerrorse.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).toList();returnR.error(400,参数校验失败,errors);}}8. 使用 Validated Record代码量直接砍一半Java 14 Record 校验 极简 DTOValidatedpublicrecordUserCreateRequest(NotBlank(message用户名不能为空)Size(min4,max20)Stringusername,NotBlankEmailStringemail,PhoneNumberStringphone){}Controller 直接用PostMapping(/users)publicvoidcreate(ValidUserCreateRequestrequest){// request.username() 访问}对比传统省去 getter/setter、equals/hashCode、toString代码量直接减半以上。9. 使用 hibernate-validator 内置的 ParameterNameProvider ConstraintValidatorContext 动态消息终极简化字段名自动映射中文提示ConfigurationpublicclassValidationConfig{BeanpublicValidatorvalidator(){ValidatorFactoryfactoryValidation.byDefaultProvider().configure().parameterNameProvider(newCustomParameterNameProvider()).buildValidatorFactory();returnfactory.getValidator();}staticclassCustomParameterNameProviderimplementsParameterNameProvider{OverridepublicListStringgetParameterNames(Constructor?constructor){returnArrays.stream(constructor.getParameters()).map(p-p.isAnnotationPresent(NotBlank.class)?用户名:p.getName()).toList();}// ...}}更推荐直接用Property或自定义MessageInterpolator。但最直接省代码的方式还是第 8 点Record Validated。总结最值得立刻掌握的三个第 1自定义复合注解复用性最高第 3分组校验同一个 DTO 多种场景第 8Record Validated代码量直接减半强烈推荐你项目里现在是用传统 DTO 还是已经开始用 Record 了或者在校验上遇到过哪些最头疼的场景可以告诉我我帮你针对性给出更优解法。