如果大家在Spring Boot中使用过Swagger,应该用过SpringFox提供的Swagger UI库,其实这个库已经不再维护了,也不支持Spring Boot 3。今天给大家分享一款更适合Spring Boot的API文档库SpringDoc,全面支持Spring Boot 3!
SpringDoc简介
SpringDoc是一款可以结合Spring Boot使用的API文档生成工具,基于OpenAPI 3,目前在Github上已有3.5K+Star,更新发版还是挺勤快的,是一款更好用的Swagger库!值得一提的是SpringDoc不仅支持Spring WebMvc项目,还可以支持Spring WebFlux项目,甚至Spring Rest和Spring Native项目,总之非常强大,下面是一张SpringDoc的架构图。
使用
接下来介绍下SpringDoc的使用,涵盖基本使用和结合Spring Security的使用。
集成及配置
首先我们需要在项目中集成SpringDoc,在pom.xml中添加它的依赖即可;
<!--SpringDoc相关依赖--> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>${springdoc-openapi.version}</version> </dependency>然后在application.yml文件中添加SpringDoc的相关配置。
springdoc: swagger-ui: # 修改Swagger UI路径 path:/swagger-ui.html # 开启Swagger UI界面 enabled:true api-docs: # 修改api-docs路径 path:/v3/api-docs # 开启api-docs enabled:true group-configs: -group:'brand' paths-to-match:'/brand/**' packages-to-scan:com.macro.blog.springdoc.controller -group:'admin' paths-to-match:'/admin/**' packages-to-scan:com.macro.blog.springdoc.controller default-flat-param-object:false和SpringFox的对比
SpringFox | SpringDoc | 注解用途 |
---|---|---|
@Api | @Tag | 用于接口类,标识这个类是Swagger的资源,可用于给接口类添加说明 |
@ApiIgnore | @Parameter(hidden = true)or@Operation(hidden = true)or@Hidden | 忽略该类的文档生成 |
@ApiImplicitParam | @Parameter | 隐式指定接口方法中的参数,可给请求参数添加说明 |
@ApiImplicitParams | @Parameters | 隐式指定接口方法中的参数集合,为上面注解的集合 |
@ApiModel | @Schema | 用于实体类,声明一个Swagger的模型 |
@ApiModelProperty | @Schema | 用于实体类的参数,声明Swagger模型的属性 |
@ApiOperation(value = "foo", notes = "bar") | @Operation(summary = "foo", description = "bar") | 用于接口方法,标识这个类是Swagger的一个接口,可用于给接口添加说明 |
@ApiParam | @Parameter | 用于接口方法参数,给请求参数添加说明 |
@ApiResponse(code = 404, message = "foo") | ApiResponse(responseCode = "404", description = "foo") | 用于描述一个可能的返回结果 |
项目演示:
接下来进行添加SpringDoc的Java配置配置,使用OpenAPI来配置基础的文档信息;
/** * @堆代码 duidaima.com * @description SpringDoc API文档相关配置 * @date 2025/8/12 * @github https://github.com/macrozheng */ @Configuration publicclass SpringDocConfig { @Bean public OpenAPI mallTinyOpenAPI() { returnnew OpenAPI() .info(new Info().title("SpringDoc API") .description("SpringDoc API文档演示") .version("v1.0.0") .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning"))) .externalDocs(new ExternalDocumentation() .description("SpringBoot实战电商项目mall(60K+Star)全套文档") .url("https://www.macrozheng.com")); } }接下来创建一个商品品牌管理的Controller,具体使用可以参考表格中的注解;
/** * @堆代码 duidaima.com * @description * @date 2025/8/12 * @github https://github.com/macrozheng */ @Tag(name = "PmsBrandController", description = "商品品牌管理") @RestController @RequestMapping("/brand") publicclass PmsBrandController { @Autowired private PmsBrandService brandService; @Operation(summary = "获取所有品牌列表",description = "需要登录后访问") @GetMapping("/listAll") public CommonResult<List<PmsBrand>> listAll() { return CommonResult.success(brandService.listAll()); } @Operation(summary = "添加品牌") @PostMapping("/create") public CommonResult create(@RequestBody PmsBrand pmsBrand) { CommonResult commonResult; int count = brandService.create(pmsBrand); if (count == 1) { commonResult = CommonResult.success(pmsBrand); } else { commonResult = CommonResult.failed("操作失败"); } return commonResult; } @Operation(summary = "更新指定id品牌信息") @PostMapping("/update/{id}") public CommonResult update(@PathVariable("id") Long id, @RequestBody PmsBrand brand) { CommonResult commonResult; int count = brandService.update(id, brand); if (count == 1) { commonResult = CommonResult.success(brand); } else { commonResult = CommonResult.failed("操作失败"); } return commonResult; } @Operation(summary = "删除指定id的品牌") @GetMapping("/delete/{id}") public CommonResult deleteBrand(@PathVariable("id") Long id) { int count = brandService.delete(id); if (count == 1) { return CommonResult.success(null); } else { return CommonResult.failed("操作失败"); } } @Operation(summary = "分页查询品牌列表") @GetMapping("/list") public CommonResult<List<PmsBrand>> list(@RequestParam(value = "pageNum", defaultValue = "1") @Parameter(description = "页码") Integer pageNum, @RequestParam(value = "pageSize", defaultValue = "3") @Parameter(description = "每页数量") Integer pageSize) { List<PmsBrand> brandList = brandService.list(pageNum, pageSize); return CommonResult.success(brandList); } @Operation(summary = "获取指定id的品牌详情") @GetMapping("/{id}") public CommonResult<PmsBrand> detail(@PathVariable("id") Long id) { return CommonResult.success(brandService.detail(id)); } }在PmsBrand实体类中可以通过@Schema注解来标注对应的属性信息。
/** * @堆代码 duidaima.com * @description 商品品牌实体类 * @date 2025/8/12 * @github https://github.com/macrozheng */ @Data publicclass PmsBrand { private Long id; private String name; @Schema(title = "首字母") private String firstLetter; private Integer sort; @Schema(title = "是否为品牌制造商:0->不是;1->是") private Integer factoryStatus; private Integer showStatus; @Schema(title = "产品数量") private Integer productCount; @Schema(title = "产品评论数量") private Integer productCommentCount; @Schema(title = "品牌logo") private String logo; @Schema(title = "专区大图") private String bigPic; @Schema(title = "品牌故事") private String brandStory; }结合Spring Security使用
/** * @description SpringDoc API文档相关配置 * @date 2025/8/12 * @github https://github.com/macrozheng */ @Configuration publicclass SpringDocConfig { privatestaticfinal String SECURITY_SCHEME_NAME = "Authorization"; @Bean public OpenAPI mallTinyOpenAPI() { returnnew OpenAPI() .info(new Info().title("SpringDoc API") .description("SpringDoc API文档演示") .version("v1.0.0") .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning"))) .externalDocs(new ExternalDocumentation() .description("SpringBoot实战电商项目mall(60K+Star)全套文档") .url("https://www.macrozheng.com")) .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME)) .components(new Components() .addSecuritySchemes(SECURITY_SCHEME_NAME, new SecurityScheme() .name(SECURITY_SCHEME_NAME) .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT"))); } }测试