Spring中OpenAPI生成代码的请求字段验证失效排查
问题排查:Spring请求体必填字段校验不生效
核心问题分析及修复方案
1. 自定义Controller方法丢失关键注解
生成的UserApi接口中,createUser方法参数明确标注了@Valid @RequestBody,但你实现的UserController里的方法参数只写了User user,缺少这两个注解:
// 错误写法 public ResponseEntity<User> createUser(User user) { ... } // 正确写法 public ResponseEntity<User> createUser(@Valid @RequestBody User user) { ... }
- 原因:
@RequestBody告诉Spring将请求体绑定到User对象,@Valid触发Bean校验逻辑。缺少这两个注解时,Spring既不会解析请求体到User实例,也不会执行校验,直接跳过校验进入业务流程。
2. 校验依赖版本冲突(Spring Boot 3.x适配问题)
你的项目基于Spring Boot 3.2.0,它依赖Jakarta EE 9规范,但当前依赖配置存在以下问题:
- 手动引入了
javax.validation:validation-api:2.0.1,这是Java EE时代的依赖,Spring Boot 3.x需要使用jakarta.validation:jakarta.validation-api。 - 在
spring-boot-starter-validation中排除了validation-api和javax.annotation-api,导致Spring无法加载正确的校验器实现。
修复方案:
- 删除单独引入的
javax.validation:validation-api依赖。 - 移除
spring-boot-starter-validation中的排除配置,让Spring Boot自动管理Jakarta版本的校验依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <!-- 移除此处的exclusions配置 --> </dependency>
3. 实体注解位置优化(可选)
生成的User实体中@NotNull标注在getDocumentNumber()方法上,虽然框架支持方法级注解,但字段级注解更直观且兼容性更好,建议调整到字段上:
public class User { @NotNull @Schema(name = "documentNumber", example = "John", requiredMode = Schema.RequiredMode.REQUIRED) @JsonProperty("documentNumber") private String documentNumber; // 其余代码... }
4. 添加全局异常处理器(可选,统一错误返回)
校验触发后,Spring会抛出MethodArgumentNotValidException,如果没有全局处理器,可能返回默认错误页面或无响应。添加全局异常处理器可以返回结构化错误信息:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } }
内容的提问来源于stack exchange,提问作者DarkVaderM
相关产品推荐
相关产品推荐

