Spring Boot中如何为POST/PUT接口动态设置@ApiModelProperty的required属性
适配POST/PUT接口必填规则的请求体实现方案
针对POST接口要求所有字段必填、PUT仅address必填的场景,以下是几种可行方案:
方案一:基于校验分组+Swagger分组(单一类实现)
通过定义校验分组和Swagger分组,让同一个实体类在不同接口下应用不同的必填规则:
- 定义校验分组接口
// POST接口专属校验分组 public interface PostStudentGroup {} // PUT接口专属校验分组 public interface PutStudentGroup {}
- 修改StudentCreation实体类
给校验注解和Swagger注解指定分组,实现不同接口下的必填逻辑:
@Data public class StudentCreation { // POST时必填,PUT时可选 @NotBlank(groups = PostStudentGroup.class) @ApiModelProperty( value = "名字", required = true, groups = PostStudentGroup.class ) @ApiModelProperty( value = "名字", required = false, groups = PutStudentGroup.class ) private String firstName; // POST时必填,PUT时可选 @NotBlank(groups = PostStudentGroup.class) @ApiModelProperty( value = "姓氏", required = true, groups = PostStudentGroup.class ) @ApiModelProperty( value = "姓氏", required = false, groups = PutStudentGroup.class ) private String lastName; // POST和PUT都必填 @NotBlank(groups = {PostStudentGroup.class, PutStudentGroup.class}) @ApiModelProperty( value = "地址", required = true, groups = {PostStudentGroup.class, PutStudentGroup.class} ) private String address; }
- 接口层指定分组
用@Validated指定校验分组,同时通过Swagger的@ApiOperation指定分组匹配文档显示:
// POST创建接口 @PostMapping("/api/v1/student") @ApiOperation(value = "创建学生", groups = PostStudentGroup.class) public ResponseEntity<Void> createStudent( @Validated(PostStudentGroup.class) @RequestBody StudentCreation request ) { // 业务逻辑实现 return ResponseEntity.ok().build(); } // PUT更新接口 @PutMapping("/api/v1/student/{student_id}") @ApiOperation(value = "更新学生", groups = PutStudentGroup.class) public ResponseEntity<Void> updateStudent( @PathVariable Long student_id, @Validated(PutStudentGroup.class) @RequestBody StudentCreation request ) { // 业务逻辑实现 return ResponseEntity.ok().build(); }
方案二:继承拆分实体类(简洁易维护)
如果觉得分组配置繁琐,可通过继承拆分公共字段与专属字段,代码直观且维护成本低:
- 公共父类(存放POST/PUT共享字段)
@Data public class BaseStudentRequest { @NotBlank @ApiModelProperty(required = true) private String address; }
- POST专属请求体
@Data public class StudentCreation extends BaseStudentRequest { @NotBlank @ApiModelProperty(required = true) private String firstName; @NotBlank @ApiModelProperty(required = true) private String lastName; }
- PUT专属请求体
@Data public class StudentUpdate extends BaseStudentRequest { @ApiModelProperty(required = false) private String firstName; @ApiModelProperty(required = false) private String lastName; }
接口层直接使用对应请求体类即可,无需额外配置。
方案三:手动校验+Swagger注解覆盖(不推荐)
若不想创建多类或配置分组,可在PUT接口手动校验必填字段,并用Swagger注解覆盖实体类默认配置,但该方式易遗漏规则,且文档与实体类分离,维护成本高:
@PutMapping("/api/v1/student/{student_id}") @ApiImplicitParams({ @ApiImplicitParam(name = "firstName", value = "名字", required = false, dataTypeClass = String.class), @ApiImplicitParam(name = "lastName", value = "姓氏", required = false, dataTypeClass = String.class), @ApiImplicitParam(name = "address", value = "地址", required = true, dataTypeClass = String.class) }) public ResponseEntity<Void> updateStudent( @PathVariable Long student_id, @RequestBody StudentCreation request ) { // 手动校验address非空 if (StringUtils.isBlank(request.getAddress())) { throw new IllegalArgumentException("地址不能为空"); } // 业务逻辑实现 return ResponseEntity.ok().build(); }
方案推荐
- 追求单一实体类时优先选方案一;
- 追求代码直观、易维护时优先选方案二,这也是多数团队的常用实践。
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

