如何为Swagger DTO对象设置默认值?@ApiModelProperty example不生效怎么办
我在查阅@ApiModelProperty相关资料时,本以为终于找到了为Swagger DTO设置默认示例值的解决方案,但实际配置后并未生效。
以下是我的相关业务代码:
Controller代码
@RestController @Api(value = "inventorySnapshot") @RequestMapping("/business/v1/inventorySnapshots") @Slf4j public class InventorySnapshotController { @ApiOperation(value = "@api.operation.summary.put_dtos@") @PutMapping public ResponseEntity<Void> put(final @RequestBody List<MyDTO> dtos) { log.debug("Put InventorySnapshots"); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } }
DTO代码
@Data @Builder @AllArgsConstructor @NoArgsConstructor public class MyDTO { @NotNull(groups = ForDocumentationOnly.class) @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd", lenient = OptBoolean.FALSE) private Date availableFromDate; @ApiModelProperty(example = "2021-01-11T11:11:11Z") @NotNull(groups = ForDocumentationOnly.class) @DateTimeFormat(pattern = "yyyy-MM-ddThh:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", lenient = OptBoolean.FALSE) private Timestamp calculationDateTime; // 其余属性我希望保留Swagger默认生成的示例值... }
实际生成效果


预期效果
我期望Swagger文档生成的字段示例效果如下:
请问该问题是什么原因导致的?有什么可行的解决方案吗?
问题原因
- 注解版本不匹配
@ApiModelProperty是Swagger 2.x(对应SpringFox 2.x/早期3.x版本)的专属注解,如果你使用的是SpringDoc OpenAPI,该注解默认不会被识别;即便是SpringFox 3.x版本,也存在部分子版本对Timestamp、Date等日期类型的example属性解析存在缺陷。 - 注解优先级冲突
字段上同时标注的@JsonFormat、@DateTimeFormat优先级高于@ApiModelProperty,部分Swagger版本会优先从日期格式化注解推导示例值,覆盖你自定义的配置。 - 集合入参解析缺陷
你的接口入参是List<MyDTO>顶层集合类型,部分旧版本Swagger对这类入参的模型解析存在bug,不会读取嵌套DTO内的@ApiModelProperty配置。
可行解决方案
- 方案1:替换为标准OpenAPI注解(推荐)
如果你的项目用的是SpringDoc或者SpringFox 3.x以上版本,直接将@ApiModelProperty(example = "2021-01-11T11:11:11Z")替换为OpenAPI 3.0标准的@Schema(example = "2021-01-11T11:11:11Z")即可,注解导入路径为io.swagger.v3.oas.annotations.media.Schema。 - 方案2:自定义模型属性构建插件(适配SpringFox 2.x)
如果无法升级依赖,可自定义Swagger插件,强制优先读取@ApiModelProperty的example值:
@Component public class ExamplePriorityPlugin implements ModelPropertyBuilderPlugin { @Override public void apply(ModelPropertyContext context) { Optional<ApiModelProperty> annotation = Optional.empty(); if (context.getAnnotatedElement().isPresent()) { annotation = Optional.ofNullable(AnnotationUtils.findAnnotation( context.getAnnotatedElement().get(), ApiModelProperty.class )); } annotation.ifPresent(anno -> { if (StringUtils.hasText(anno.example())) { context.getBuilder().example(anno.example()); } }); } @Override public boolean supports(DocumentationType delimiter) { return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter); } }
- 方案3:适配集合入参
如果是集合入参解析问题,可将顶层集合包装为单独的请求DTO:
@Data public class MyDTORequest { private List<MyDTO> dtos; }
再将Controller接口入参改为@RequestBody MyDTORequest request即可。
- 方案4:升级依赖版本
SpringFox 2.9.x版本对日期类型的示例解析bug较多,可直接升级到SpringFox 2.10.5,或是迁移到SpringDoc OpenAPI,兼容性会大幅提升。
内容的提问来源于stack exchange,提问作者payne
相关产品推荐
相关产品推荐

