SpringBoot实战:接口参数校验与优雅处理
接口参数校验是后端开发的第一道防线。与其在业务代码中写满if (name null)不如使用 Spring Boot 提供的参数校验机制让代码更简洁、逻辑更清晰。一、 为什么需要参数校验在早期的开发中我们经常在 Service 层写大量的防御性代码publicvoidcreateUser(UserDTOdto){if(StringUtils.isEmpty(dto.getName())){thrownewIllegalArgumentException(用户名不能为空);}if(dto.getAge()null||dto.getAge()0){thrownewIllegalArgumentException(年龄必须为正数);}if(!dto.getEmail().matches(^[\\w-\\.]([\\w-]\\.)[\\w-]{2,4}$)){thrownewIllegalArgumentException(邮箱格式不正确);}// ... 业务逻辑}这种方式的缺点显而易见代码臃肿校验逻辑与业务逻辑混杂难以阅读。维护困难一旦校验规则变更需要修改多处代码。复用性差同样的 DTO 在不同接口中可能需要不同的校验规则。Spring Boot 整合了 Hibernate Validator实现了 Bean Validation 规范为我们提供了声明式的参数校验方案。二、 快速上手1. 引入依赖在 Spring Boot 2.3.x 之前spring-boot-starter-web已经包含了 validation 依赖。但在Spring Boot 2.3.x 及之后需要显式引入dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency2. 定义 DTO 并添加注解我们在 DTOData Transfer Object的字段上直接添加校验注解DatapublicclassUserDTO{NotBlank(message用户名不能为空)Size(min2,max20,message用户名长度必须在 2-20 之间)privateStringusername;NotNull(message年龄不能为空)Min(value0,message年龄必须大于等于 0)Max(value150,message年龄必须小于等于 150)privateIntegerage;Email(message邮箱格式不正确)privateStringemail;}3. Controller 层开启校验在 Controller 的方法参数前添加Valid或Validated注解RestControllerRequestMapping(/user)publicclassUserController{PostMappingpublicResultVoidcreateUser(ValidRequestBodyUserDTOuserDTO){// 如果参数校验失败程序不会进入这里而是抛出 MethodArgumentNotValidExceptionuserService.createUser(userDTO);returnResult.success();}}三、 进阶用法1.ValidvsValidatedValid: 属于 JSR-303 标准支持嵌套校验即如果一个对象内部包含另一个对象内部对象的注解也会被校验。Validated: 是 Spring 提供的注解功能更强大支持分组校验但默认不支持嵌套校验需要配合Valid使用。通常在 Controller 参数上使用Validated在 DTO 内部嵌套对象上使用Valid。2. 自定义校验注解当内置注解无法满足需求时例如校验手机号我们可以自定义注解。Step 1: 定义注解Target({ElementType.FIELD,ElementType.PARAMETER})Retention(RetentionPolicy.RUNTIME)DocumentedConstraint(validatedByPhoneValidator.class)// 指定校验器publicinterfacePhone{Stringmessage()default手机号格式不正确;Class?[]groups()default{};Class?extendsPayload[]payload()default{};}Step 2: 实现校验器publicclassPhoneValidatorimplementsConstraintValidatorPhone,String{privatestaticfinalStringPHONE_REGEX^1[3-9]\\d{9}$;OverridepublicbooleanisValid(Stringvalue,ConstraintValidatorContextcontext){if(StringUtils.isEmpty(value)){returntrue;// 是否为空由 NotBlank/NotNull 控制这里只校验格式}returnvalue.matches(PHONE_REGEX);}}Step 3: 使用DatapublicclassUserDTO{// ... 其他字段Phone(message请输入有效的手机号码)privateStringphone;}3. 分组校验 (Validation Groups)同一个 DTO 在“创建”和“更新”场景下校验规则可能不同。例如创建时id应该为空更新时id必须有值。定义分组接口publicinterfaceCreateGroup{}publicinterfaceUpdateGroup{}配置 DTO 分组DatapublicclassUserDTO{Null(message创建用户时 ID 必须为空,groupsCreateGroup.class)NotNull(message更新用户时 ID 不能为空,groupsUpdateGroup.class)privateLongid;NotBlank(message用户名不能为空,groups{CreateGroup.class,UpdateGroup.class})privateStringusername;}Controller 中指定分组PostMappingpublicResultVoidcreateUser(Validated(CreateGroup.class)RequestBodyUserDTOuserDTO){// ...}PutMappingpublicResultVoidupdateUser(Validated(UpdateGroup.class)RequestBodyUserDTOuserDTO){// ...}注意使用分组校验时如果字段没有指定groups默认属于Default组。如果指定了groups则不再属于 Default 组。这意味着如果 Controller 使用Validated不加参数即 Default 组那些指定了自定义 Group 的注解将不会生效。四、 异常处理集成参数校验失败时会抛出异常。对于RequestBody参数抛出的是MethodArgumentNotValidException对于RequestParam或路径参数抛出的是ConstraintViolationException。我们需要在全局异常处理器中统一捕获它们RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(MethodArgumentNotValidException.class)publicResult?handleValidationException(MethodArgumentNotValidExceptione){Stringmessagee.getBindingResult().getFieldErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(, ));returnResult.fail(400,message);}ExceptionHandler(ConstraintViolationException.class)publicResult?handleConstraintViolation(ConstraintViolationExceptione){Stringmessagee.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(, ));returnResult.fail(400,message);}}五、 最佳实践总结DTO 与 Entity 分离校验注解通常加在 DTO 上不要直接加在数据库实体 Entity 上。快速失败 (Fail-Fast)默认情况下Validator 会校验所有字段并收集错误。如果希望发现第一个错误就停止可以在类上添加GroupSequence或者自定义 Validator 实现逻辑。明确错误提示每个校验注解都应该指定清晰的message方便前端直接展示给用户。嵌套对象校验如果 DTO 中包含对象如AddressDTO address需要在字段上同时添加Valid才能触发内部对象的校验。复杂逻辑校验对于跨字段校验如“密码”与“确认密码”必须一致建议使用自定义 Class 级别的校验注解。六、 总结参数校验是系统安全的第一道关卡。通过 Spring Validation 框架我们将散落在各处的if-else转化为声明式的注解配合全局异常处理实现了一套既优雅又强大的参数校验方案。掌握这些技巧让你的接口开发事半功倍 福利时间如果你正在备战面试或者想要学习其他知识给大家推荐一个宝藏知识库作者整理了一些列 Java 程序员需要掌握的核心知识有需要的自取不谢。知识库地址https://farerboy.com/

相关新闻

剪映AI配音黑科技曝光:绕过语音克隆限制的3种合法路径(含实操录屏)

剪映AI配音黑科技曝光:绕过语音克隆限制的3种合法路径(含实操录屏)

更多请点击: https://intelliparadigm.com 第一章:剪映AI配音黑科技曝光:绕过语音克隆限制的3种合法路径(含实操录屏) 剪映PC端自v4.0起对AI配音功能实施了严格的语音克隆权限管控,仅限认证企业账号调用“…

2026/10/15 17:00:31 阅读更多 →
从零搭建AI视觉品牌系统,深度拆解头部品牌私有化训练数据集构建全流程

从零搭建AI视觉品牌系统,深度拆解头部品牌私有化训练数据集构建全流程

更多请点击: https://kaifayun.com 第一章:AI品牌视觉设计的范式演进与战略定位 AI驱动的品牌视觉设计已从静态符号系统,跃迁为具备感知力、响应性与成长性的动态认知接口。这一转变不仅源于生成式AI技术的成熟,更根植于用户对品…

2026/10/15 17:00:20 阅读更多 →
JAVA毕设项目:基于 SpringBoot+Vue 的工业物资物联网仓储智能管理系统实现 智慧库房实时监控与库存统计分析系统 (源码+文档,讲解、调试运行,定制等)

JAVA毕设项目:基于 SpringBoot+Vue 的工业物资物联网仓储智能管理系统实现 智慧库房实时监控与库存统计分析系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/10/15 17:09:35 阅读更多 →

最新新闻

对抗特征幻觉AFHN:小样本学习的特征增广新思路

对抗特征幻觉AFHN:小样本学习的特征增广新思路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:09:31 阅读更多 →
ATS备自投控制逻辑全解析:设计、整定与调试要点

ATS备自投控制逻辑全解析:设计、整定与调试要点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:09:31 阅读更多 →
2S磷酸铁锂主动均衡系统设计:基于STM32F767与MP2642GR-Z的实战解析

2S磷酸铁锂主动均衡系统设计:基于STM32F767与MP2642GR-Z的实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:09:31 阅读更多 →
MyBatis处理MySQL ZEROFILL丢零的通用方案

MyBatis处理MySQL ZEROFILL丢零的通用方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:09:31 阅读更多 →
Spring Boot与Spring Cloud版本对应关系全解析:兼容矩阵与升级避坑指南

Spring Boot与Spring Cloud版本对应关系全解析:兼容矩阵与升级避坑指南

隔三差五就会有人在群里发一句:Spring Boot 3.2.5 该配哪版 Spring Cloud?是 2022.0.x 还是 2023.0.x?又或者:项目还在 JDK 8,Boot 用 2.7.18,Cloud 用 2021.0.8 行不行?这些问题的本质&#xf…

2026/10/16 5:09:31 阅读更多 →
Coder 平台深度解析:环境即代码与云端开发环境搭建指南

Coder 平台深度解析:环境即代码与云端开发环境搭建指南

1. 从“coder”这个标题说起:它到底指什么“coder”这个词,放在今天的技术语境里,含义比五年前宽泛了太多。早些年,它基本就是“写代码的人”的代称,跟 programmer、developer 混着用。但现在你搜“coder”&#xff0c…

2026/10/16 5:08:31 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →