参数校验失败需统一结构化处理:java用@restcontrolleradvice捕获methodargumentnotvalidexception并提取field和message;python用fastapi的requestvalidationerror处理器解析errors();php则主动分层校验并聚合错误;三者均须返回中文提示、字段名及全部错误,http状态码分别设为400或422。

参数校验失败时,异常信息不能直接透传给前端,而要提取关键字段、过滤敏感内容、统一结构化输出。核心是“拦截—解析—重组”,不同语言框架有对应原生机制,无需手动 try-catch 每个接口。
Java(Spring Boot):用 @RestControllerAdvice 拦截 MethodArgumentNotValidException
这是最标准的处理路径。当控制器方法使用 @Valid 或 @Validated 校验 DTO 时,失败会抛出 MethodArgumentNotValidException,它携带完整的 BindingResult。
- 在全局异常处理器中添加对应方法,明确捕获该异常类型
- 调用 exception.getBindingResult().getFieldErrors() 获取所有字段错误
- 对每个 FieldError 提取 field(字段名)、getDefaultMessage()(中文提示)、避免返回 rejectedValue(可能含敏感值)和 codes(如 NotBlank.user.name)
- 组装为统一响应体,例如:{"code":40001,"msg":"参数校验失败","details":[{"field":"email","message":"邮箱格式不正确"},{"field":"password","message":"密码长度不能少于6位"}]}
- HTTP 状态码设为 400,符合语义
Python(FastAPI):重写 RequestValidationError 处理器
FastAPI 基于 Pydantic v2,校验失败抛出 RequestValidationError。它的 exc.errors() 方法返回结构清晰的字典列表,比 exc.json() 更适合前端消费。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用 @app.exception_handler(RequestValidationError) 注册处理器
- 遍历 exc.errors(),取 error['loc'][-1] 得到字段名(如 email),error['msg'] 得到提示(如“邮箱格式不正确”)
- 忽略 error['type'] == "missing" 等非业务强提示项,可选过滤
- 返回 JSONResponse(status_code=422, content={"detail": errors}),状态码 422 更贴合语义(Unprocessable Entity)
PHP:分层校验 + 结构化 JSON 返回
PHP 没有注解驱动的自动校验,需主动设计。重点在于类型兜底、值校验、错误聚合三步走。
- 开启 declare(strict_types=1),让错误类型直接抛 TypeError,无需手动判断
- 值校验时用 filter_var($email, FILTER_VALIDATE_EMAIL) 替代正则,用 mb_strlen($name, 'UTF-8') 防中文截断
- 收集所有错误到数组:$errors[] = ['field' => 'mobile', 'msg' => '手机号格式不正确']
- 最终返回 json_encode(['code' => 422, 'msg' => '参数校验失败', 'errors' => $errors]),HTTP 状态码设为 422
关键原则:面向用户,不暴露实现细节
无论哪种语言,都要守住三条底线:
- 错误提示必须是自然中文(或对应语言),不是 javax.validation.constraints.Email.message 这类技术字符串
- 必须包含 出问题的字段名,方便前端定位并高亮输入框
- 多个错误要一次性返回全部,不要只取第一个,避免用户反复提交试错










