SpringBoot API参数校验

一、核心说明

本文整理了SpringBoot项目开发中,API参数校验最核心的三项实战能力,均为企业项目通用落地方案。内容精简实用,无冗余理论,包含可直接上线使用的完整代码、开发规则、易错点及统一返回规范,适配日常开发、功能迭代及接口标准化整改场景。

三大核心:请求体Body自动化校验、查询参数Query自动化校验、全局统一错误返回格式

1.必备前置依赖 SpringBoot2.3+ 必须手动引入,提供所有校验注解能力

复制代码

js

体验AI代码助手

代码解读

复制代码

<?xml version="1.0" encoding="UTF-8"?> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.7.0</version> </dependency> </dependencies>

二、请求体(Body)参数校验【POST/PUT】

  1. 核心规则 主要用于POST、PUT请求的复杂入参场景,支持对象、嵌套对象、集合类参数校验。通过@Valid注解开启自动化校验,覆盖全部基础校验规则,开发中无需手写大量if判断,代码更简洁规范。
  2. 核心校验注解区分(必记)
  • @NotNull:数值、对象非空
  • @NotBlank:字符串非空
  • @NotEmpty:集合、字符串非空
  • @Min/@Max:数值范围限制
  • @Size:字符串/集合长度限制
  • @Pattern:正则格式校验

3.核心DTO代码

复制代码

pyton

体验AI代码助手

代码解读

复制代码

from dataclasses import dataclass from typing import List, Optional from decimal import Decimal import re class ValidationError(Exception): def __init__(self, field, message): self.field = field self.message = message super().__init__(f"{field}: {message}") @dataclass class OrderItemDTO: goods_id: int count: int def validate(self): errors = [] if self.goods_id is None: errors.append(ValidationError("goodsId", "商品ID不能为空")) elif self.goods_id < 1: errors.append(ValidationError("goodsId", "商品ID非法")) if self.count is None: errors.append(ValidationError("count", "购买数量不能为空")) elif self.count < 1: errors.append(ValidationError("count", "数量不能小于1")) if errors: raise ValueError("; ".join([f"{e.field}: {e.message}" for e in errors])) @dataclass class OrderCreateDTO: user_id: int phone: str amount: Decimal item_list: List[OrderItemDTO] remark: Optional[str] = None def validate(self): errors = [] # 用户ID校验 if self.user_id is None: errors.append(ValidationError("userId", "用户ID不能为空")) elif self.user_id < 1: errors.append(ValidationError("userId", "用户ID取值非法")) # 手机号校验 if not self.phone or not self.phone.strip(): errors.append(ValidationError("phone", "手机号不能为空")) elif not re.match(r"^1[3-9]\d{9}$", self.phone): errors.append(ValidationError("phone", "手机号格式错误")) # 订单金额校验 if self.amount is None: errors.append(ValidationError("amount", "订单金额必须大于0")) elif self.amount <= 0: errors.append(ValidationError("amount", "订单金额必须大于0")) # 备注长度校验 if self.remark and len(self.remark) > 500: errors.append(ValidationError("remark", "备注不能超过500字符")) # 商品列表校验 if not self.item_list: errors.append(ValidationError("itemList", "商品列表不能为空")) else: for i, item in enumerate(self.item_list): try: item.validate() except ValueError as e: errors.append(ValidationError(f"itemList[{i}]", str(e))) if errors: raise ValueError("; ".join([f"{e.field}: {e.message}" for e in errors])) # 使用示例 if __name__ == "__main__": # 创建订单项目 item1 = OrderItemDTO(goods_id=123, count=2) item2 = OrderItemDTO(goods_id=456, count=1) # 创建订单 order = OrderCreateDTO( user_id=1001, phone="13812345678", amount=Decimal("99.99"), item_list=[item1, item2], remark="请尽快发货" ) try: order.validate() print("订单验证通过") except ValueError as e: print(f"验证失败: {e}")

  1. Controller开启校验
复制代码

java

体验AI代码助手

代码解读

复制代码

package com.example.controller; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @RestController @RequestMapping("/api/order") public class OrderController { @PostMapping("/create") public ResultVO<String> createOrder(@Valid @RequestBody OrderCreateDTO orderDTO) { return ResultVO.success("订单创建成功"); } }``` 开发高频易错点:如果参数中存在嵌套对象、集合嵌套,仅在顶层参数加@Valid无法生效,嵌套层级必须单独添加@Valid注解,否则子参数校验失效,出现参数穿透问题 # 三、查询参数(Query)校验 适用于GET请求的分页查询、条件筛选、排序等简单参数场景,是查询参数专属校验方式。和请求体校验用法有明显区别,不需要在方法参数上加@Valid **1.分页参数DTO** ```python from dataclasses import dataclass from typing import Optional class ValidationError(Exception): def __init__(self, field, message): self.field = field self.message = message super().__init__(f"{field}: {message}") @dataclass class PageQueryDTO: pageNum: int = 1 pageSize: int = 10 sortField: Optional[str] = None sortType: Optional[str] = None def validate(self): errors = [] # 页码校验 if self.pageNum is None or self.pageNum < 1: errors.append(ValidationError("pageNum", "页码不能小于1")) # 每页大小校验 if self.pageSize is None or self.pageSize < 1: errors.append(ValidationError("pageSize", "每页大小不能小于1")) elif self.pageSize > 100: errors.append(ValidationError("pageSize", "每页最大100条,防止全表查询")) # 排序字段校验 if self.sortField: import re if not re.match(r"^[a-zA-Z0-9_]{1,30}$", self.sortField): errors.append(ValidationError("sortField", "排序字段非法")) # 排序方式校验 if self.sortType: if self.sortType.lower() not in ["asc", "desc"]: errors.append(ValidationError("sortType", "排序方式仅支持asc/desc")) if errors: raise ValueError("; ".join([f"{e.field}: {e.message}" for e in errors]))``` **2.Controller开启校验** ```python // 仅需在类上加@Validated,全局开启Query/路径参数校验 @Validated @RestController @RequestMapping("/api/user") public class UserController { @GetMapping("/page") public ResultVO<Object> getUserPage(PageQueryDTO pageQueryDTO) { return ResultVO.success("查询成功", null); } }

四、全局统一错误返回格式

项目原生的参数校验异常会直接抛出堆栈信息,前端无法解析、页面展示异常,还会暴露项目结构。通过全局统一异常处理,可统一接口返回格式,屏蔽错误堆栈,提示信息精准友好,适配前后端联调规范 1.统一返回实体ResultVO

复制代码

python

体验AI代码助手

代码解读

复制代码

from typing import TypeVar, Generic, Optional T = TypeVar('T') class ResultVO(Generic[T]): """API结果封装类""" def __init__(self, code: int = None, msg: str = None, data: T = None): self.code = code self.msg = msg self.data = data @classmethod def success(cls, msg: str, data: T = None): """成功响应""" result = cls() result.code = 200 result.msg = msg result.data = data return result @classmethod def success_simple(cls, msg: str): """成功响应(无数据)""" return cls.success(msg, None) @classmethod def param_error(cls, msg: str): """参数错误响应""" result = cls() result.code = 400 result.msg = msg return result @classmethod def error(cls, msg: str): """系统异常响应""" result = cls() result.code = 500 result.msg = msg return result def to_dict(self): """转为字典格式""" return { 'code': self.code, 'msg': self.msg, 'data': self.data } # 使用示例 if __name__ == "__main__": # 成功响应 success_result = ResultVO.success("操作成功", {"id": 1, "name": "test"}) print(success_result.to_dict()) # 参数错误响应 param_error_result = ResultVO.param_error("参数校验失败") print(param_error_result.to_dict()) # 系统错误响应 error_result = ResultVO.error("系统异常") print(error_result.to_dict())``` **全局异常处理器** ```python from flask import Flask, request, jsonify from werkzeug.exceptions import HTTPException import logging app = Flask(__name__) class ValidationError(Exception): """参数校验异常""" def __init__(self, message): self.message = message super().__init__(message) class ResultVO: """API结果封装类""" @staticmethod def param_error(msg: str): return { 'code': 400, 'msg': msg, 'data': None } @staticmethod def error(msg: str): return { 'code': 500, 'msg': msg, 'data': None } @staticmethod def success(msg: str, data=None): return { 'code': 200, 'msg': msg, 'data': data } @app.errorhandler(ValidationError) def handle_validation_error(error): """处理参数校验异常""" return jsonify(ResultVO.param_error(error.message)), 400 @app.errorhandler(HTTPException) def handle_http_exception(error): """处理HTTP异常""" return jsonify(ResultVO.param_error(f"请求错误: {error.description}")), error.code @app.errorhandler(Exception) def handle_all_exceptions(error): """全局异常处理器""" # 记录错误日志 logging.error(f"系统错误: {str(error)}", exc_info=True) return jsonify(ResultVO.error("系统繁忙,请稍后重试")), 500 # 示例路由用于测试 @app.route('/test-validation', methods=['POST']) def test_validation(): data = request.get_json() or {} # 模拟参数校验 if not data.get('name'): raise ValidationError("姓名不能为空") if not isinstance(data.get('age'), int) or data['age'] < 0: raise ValidationError("年龄必须为非负整数") return jsonify(ResultVO.success("验证通过")) if __name__ == '__main__': app.run(debug=True)``` # 总结 这套API参数校验方案是SpringBoot项目的标准化通用方案,核心由请求体校验、查询参数校验、统一异常返回三部分组成,覆盖绝大多数接口开发场景。针对新增、修改类POST/PUT接口,采用@Valid注解实现复杂嵌套参数的全自动校验,从源头避免参数漏验、非法参数穿透业务层的问题;针对GET查询、分页接口,通过类注解@Validated快速完成简单参数的合法性校验,有效防止越界查询、非法字段查询导致的数据库性能问题。 配合全局异常处理器,统一拦截所有参数校验异常,规整接口返回格式,隐藏底层异常堆栈,既保障了系统安全性,又提升了前后

相关推荐
霸道流氓气质1 小时前
Spring Boot 文件上传大小限制配置全解析
spring boot·后端·firefox
何以解忧,唯有..1 小时前
Go 语言安装与环境配置完整指南
开发语言·后端·golang
alwaysrun1 小时前
C++之常量体系const
c++·后端·程序员
武子康1 小时前
Java-24 深入浅出 Spring 全景:从起源到 Spring 6 一文打通 IoC / AOP / 发展史
java·后端·spring
zyk_computer1 小时前
AI Agent ,让循环收敛的那套闭环控制系统
人工智能·后端·python·ai·架构·agent·ai agent
asdfg12589631 小时前
通俗理解软件开发中前后端开发的架构模式(后端逻辑分层的“三层架构”和前端逻辑分层的“MVC 模式”)
java·架构模式
-Thinker2 小时前
【无标题】
java·开发语言·算法·图搜索
王五周八2 小时前
Tesseract OCR的Java使用(附安装包,非常详细)
java·开发语言·ocr
旧书包的青春2 小时前
2026年6月11日
java