告别Swagger UI!SpringBoot整合SpringDoc OpenAPI:更强大的API文档新选择_springdoc-openapi-ui
文章目录
- SpringDoc是什么
-
- 与 Swagger 的关系
- 为什么要选择SpringDoc
- 正式开始
-
- 最小化配置使用
- SpringDoc中简单分组配置(包含编程式配置与声明式配置)
-
- 方式一:编程式配置(灵活性高、扩展性强、调试友好)
- 方式二:声明式配置(配置集中管理、可使用多配置文件进行环境隔离)
- 如果项目中重写了WebMvcConfigurer的addResourceHandlers方法,所需进行的处理
- 如果项目引入了SpringSecurity需要进行的处理
- 总结
SpringDoc是什么
SpringDoc 是一个专为 Spring Boot 应用设计的库,能够自动生成符合 OpenAPI 3 规范的 API 文档。它通过扫描项目中的控制器、方法注解及配置,动态生成 JSON/YAML/HTML 格式的文档,并提供交互式界面(如 Swagger UI)供开发者查看和测试 API
与 Swagger 的关系
Swagger 作为 OpenAPI 规范的前身,贡献了 API 设计理念并推动了 OpenAPI 的标准化。其核心工具 Swagger UI 用于展示交互式文档。
SpringDoc 并非 Swagger 的替代品,而是基于 OpenAPI 3 规范的实现工具,并天然集成 Swagger UI 作为文档展示界面
为什么要选择SpringDoc
在SpringDoc面世之前,Spring生态中集成实现Swagger的技术为SpringFox,SpringFox与Swagger之间的协作关系如下
- SpringFox
- Swagger
- 可视化文档渲染:将 SpringFox 生成的 JSON 文件解析为交互式网页,通过浏览器访问(如 http://localhost:8080/swagger-ui.html)
- 提供接口列表、参数说明、请求示例,并支持在线测试 API(可直接发送请求并查看响应)
- 标准化规范支持:Swagger 定义 OpenAPI 规范(原 Swagger 规范),为 API 描述提供统一标准(如接口路径、请求方法、数据类型),SpringFox 生成的 JSON 文件完全遵循此规范,确保与其他 Swagger 工具(如 Swagger Editor)兼容
- 协作流程
- 开发阶段:开发者在 Spring 控制器中添加 Swagger 注解(如 @Api、@ApiParam),描述接口细节
- 运行时:SpringFox 扫描代码并生成 JSON 文档
- 展示阶段:Swagger UI 读取 JSON 文件,渲染为可视化界面供团队使用
在2020时,由于SpringFox官方基本停止维护,不再发布新版本或修复问题,再加上他无法适配 Spring Boot 2.6+ 及 3.x 版本,导致与新版本 Spring 生态冲突(如路径匹配失效、注解不兼容)。以及配置的复杂性导致他逐渐退出市场
转而由更新的技术–SpringDoc接过接力棒,SpringDoc完美支持 Spring Boot 2.6+ 及 3.x(含 JDK 17+),并且原生支持OpenAPI 3 规范,除此之外,如果不需要特殊的复杂配置,甚至可以零配置,仅需引入一个依赖,即可实现开箱即用,还有他直接使用 JSR-303 规范注解(如 @Schema、@Parameter),替代 SpringFox 的专属注解(如 @ApiModel),降低了开发人员的学习成本
正式开始
最小化配置使用
不多说废话了,下面我们正式开始,首先我们先介绍最简单,最小化的引入以及使用方式
第一步:引入Jar包
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.5.0</version> </dependency>
第二步:配置配置文件
正常使用SpringDoc,或多或少都会进行一些配置文件的配置,但是由于这里是进行最小化配置,所以这里不进行配置文件配置,仅仅介绍几个重要配置的默认项,给大家一个基础印象,方便大家理解后面运行时为什么要这样做,当然,如果不感兴趣的小伙伴也可以直接跳过,跟着步骤走,并不影响使用
# application.ymlspringdoc: # SpringDoc的API包扫描路径,如果不配置,SpringDoc 自动扫描整个项目类路径,它会自动识别所有 @RestController、@RequestMapping 等注解,生成 API 文档 packages-to-scan: com.example.controller swagger-ui: # 是否开启swagger界面,依赖OpenApi,默认为true,如果要开启需要OpenApi同时开启 enabled: true # 内置 Swagger UI 的访问路径,默认值为/swagger-ui/index.html path: /swagger-ui/index.html # 指定OpenAPI文档的URL(注意这里一定要与api-docs.path保持一致,否则会请求失败) url: /v3/api-docs # 是否禁用Swagger UI自带的示例接口(如 Petstore 等默认接口),默认值为false,仅展示当前项目的 API disable-swagger-default-url: false api-docs: # 是否启用OpenAPI文档端点,默认为true enabled: true # OpenAPI 3规范的文档访问路径,默认值为/v3/api-docs path: /api-docs
第三步:添加一个配置类,用于设置Swagger-UI页面的一些基础信息的展示
@Configuration@OpenAPIDefinition(info = @Info( title = \"项目API文档\", version = \"1.0\", description = \"SpringBoot项目接口文档\"))public class SpringDocConfig { // 无需额外配置,注解已定义基本信息}
到这一步:其实已经可以访问页面,观看效果了(访问链接为:http://localhost:8080/swagger-ui/index.html,注意如果上方配置文件修改了,这里要替换为对应的链接,我这里没有修改所以使用默认链接),只是项目如果没有任何controller,这里会展示空页面,如下:
第四步:在需要显示的Controller方法上加上注解,用于给方法添加备注,如下会展示不加注解与加注解的区别
不加注解:
@RestController@RequestMapping(\"/main\")public class MainController {@GetMapping(\"/index\")public String index(String str1) {return \"请求成功\";}}
添加注解
@RestController@RequestMapping(\"/main\")@Tag(name = \"演示controller\", description = \"演示controller\")public class MainController {@GetMapping(\"/index\")@Operation(summary = \"演示方法\", description = \"演示方法的注释\")public String index(@Parameter(description = \"参数1\", required = true) String str1) {return \"请求成功\";}}
至此为止,SpringDoc的最小化使用已经全部完成(请注意,以上所有配置生效的前提是,当前Spring项目未添加任何过滤器、拦截器,以及未使用SpringSecurity等安全框架,否则,仅仅进行最小化配置是无法运行的,因为一些默认配置可能会被拦截,如果需要更复杂配置,请继续往下看)
SpringDoc中简单分组配置(包含编程式配置与声明式配置)
上方仅仅只是展示了SpringDoc的最基础用法,接下来,我们展示SpringDoc的一种常用用法:分组,先上效果图,让大家了解是个什么功能
接下来开始进行详细配置:
方式一:编程式配置(灵活性高、扩展性强、调试友好)
@Configuration@OpenAPIDefinition(info = @Info(title = \"项目API文档\",version = \"1.0\",description = \"SpringBoot项目接口文档\"))public class SpringDocConfig {/** * 商品分组的配置(使用请求路径扫描的方式进行配置) * @return org.springdoc.core.models.GroupedOpenApi * @author ren * @date 2025/07/06 17:17 */@Beanpublic GroupedOpenApi userGroup() {// 使用路径匹配方式:仅包含 /api/product/** 下的接口return GroupedOpenApi.builder().group(\"商品模块\").pathsToMatch(\"/api/product/**\") // 路径匹配.build();}/** * 会员分组的配置(使用包扫描的方式进行配置) * @return org.springdoc.core.models.GroupedOpenApi * @author ren * @date 2025/07/06 17:17 */@Beanpublic GroupedOpenApi productGroup() {// 使用包扫描方式:扫描 com.ren.main.controller.member 包下的所有接口return GroupedOpenApi.builder().group(\"用户模块\").packagesToScan(\"com.ren.main.controller.member\") // 包扫描.build();}}
这种配置方式的原理是通过添加GroupedOpenApi类型的Bean,项目启动时,SpringDoc会寻找环境中是否存在GroupedOpenApi类型的Bean,如果存在,则会创建分组进行展示
注意:
- 一旦这里配置了分组方式展示,那么在application.yml配置文件中配置的springdoc.packages-to-scan就会失效,因为SpringDoc的扫描机制,分组配置的扫描路径优先级大于配置文件配置的扫描优先级
- 路径扫描有两种方式,一种是根据请求路径进行扫描,一种是根据包路径进行扫描,上方都有进行配置
- 如果多个分组中有重合的路径,也就是说一个接口在多个分组配置的路径中都能扫描到,那么这个接口会存在于多个分组中
以下展示我的代码结构,方便大家理解:
大家会发现,我的目录中有一个MainController的内容,在页面中没有展示了,这是为什么呢?原因我上面提过了,因为分组的配置会覆盖默认配置与配置文件配置,而分组配置中由于没有包含MainController的内容,所以,MainController的内容没有地方展示了
那么如果想要展示出这个文件中的接口该怎么办呢?很简单,在分组中再加一个默认分组,用于展示所有接口内容即可,如下
@Configuration@OpenAPIDefinition(info = @Info(title = \"项目API文档\",version = \"1.0\",description = \"SpringBoot项目接口文档\"))public class SpringDocConfig {/** * 默认分组 * @return org.springdoc.core.models.GroupedOpenApi * @author ren * @date 2025/07/06 17:38 */@Beanpublic GroupedOpenApi defaultGroup() {return GroupedOpenApi.builder().group(\"默认分组\").pathsToMatch(\"/**\") // 路径匹配.build();}/** * 商品分组的配置(使用请求路径扫描的方式进行配置) * @return org.springdoc.core.models.GroupedOpenApi * @author ren * @date 2025/07/06 17:17 */@Beanpublic GroupedOpenApi userGroup() {// 使用路径匹配方式:仅包含 /api/product/** 下的接口return GroupedOpenApi.builder().group(\"商品模块\").pathsToMatch(\"/api/product/**\") // 路径匹配.build();}/** * 会员分组的配置(使用包扫描的方式进行配置) * @return org.springdoc.core.models.GroupedOpenApi * @author ren * @date 2025/07/06 17:17 */@Beanpublic GroupedOpenApi productGroup() {// 使用包扫描方式:扫描 com.ren.main.controller.member 包下的所有接口return GroupedOpenApi.builder().group(\"用户模块\").packagesToScan(\"com.ren.main.controller.member\") // 包扫描.build();}}
配置后展示的内容
看上面的图,MainController的内容展示在这里了,同时ProductController和MemberController的内容也展示在这里了,这是为什么呢,原因我上面说过了,如果一个请求被多个分组扫描到,那么他会展示在多个分组中
方式二:声明式配置(配置集中管理、可使用多配置文件进行环境隔离)
springdoc: group-configs: - group: \'默认分组\' paths-to-match: \'/**\' - group: \'商品模块\' paths-to-match: \'/api/product/**\' - group: \'用户模块\' packages-to-scan: \'com.ren.main.controller.member\'
如上:效果与方式一相同
如果项目中重写了WebMvcConfigurer的addResourceHandlers方法,所需进行的处理
WebMvcConfigurer
- WebMvcConfigurer 是 Spring MVC 的配置中枢,用于定制化 Spring MVC 的各种行为。它不是过滤器或拦截器,而是一个配置接口(类似汽车的仪表盘),让你调整 Spring MVC 的运行方式。
- 他所拥有的方法
- addInterceptors(registry):注册拦截器
- addCorsMappings(registry):配置跨域权限
- addResourceHandlers(registry):指定静态资源路径
- addViewControllers(registry):设置简易页面跳转
- configureMessageConverters(list):定制JSON/XML解析器
- configurePathMatch(configurer):调整URL匹配规则
- addArgumentResolvers(list):自定义请求参数处理器
- addReturnValueHandlers(list):自定义返回值处理器
- configureContentNegotiation(configurer):内容协商配置(响应格式协商)
如果我们重写了WebMvcConfigurer的addResourceHandlers方法,那么原本Spring自己默认配置的所有的静态资源的指向路径就全都会失效,于是就需要我们自己去配置指定
@Configurationpublic class ResourcesConfig implements WebMvcConfigurer{@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(\"/swagger-ui/**\") .addResourceLocations(\"classpath:/META-INF/resources/webjars/springdoc-openapi-ui/\") .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic()); }}
按照如上设置后,SpringDoc将恢复正常(注意新版的SpringDoc和老版的SpringFox配置有所区别,这里只展示新版SpringDoc的配置方法)如果大家对老版配置有需要,可以留言,留言人多会单独出一期
如果项目引入了SpringSecurity需要进行的处理
由于项目引入了SpringSecurity,导致如果项目不经过认证无法访问系统资源,我们就需要在SpringSecurity的配置文件中放开SpringDoc相关的静态资源的拦截,如下
@Configuration@EnableWebSecurity@EnableMethodSecurity public class SecurityConfig { /* * 配置过滤器链 * @param http * @return org.springframework.security.web.SecurityFilterChain * @author ren * @date 2025/04/17 21:30 */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth // 允许 OPTIONS 方法通过 .requestMatchers(HttpMethod.OPTIONS, \"/**\").permitAll() // 静态资源,可匿名访问 .requestMatchers(request -> { String path = request.getServletPath(); return (request.getMethod().equals(\"GET\") && ( \"/\".equals(path) || path.endsWith(\".html\") || path.endsWith(\".css\") || path.endsWith(\".js\"))); }).permitAll() .requestMatchers(\"/swagger-ui/**\", \"/*/api-docs/**\", \"/swagger-resources/**\", \"/webjars/**\", \"/druid/**\") .permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() ); return http.build(); }}
添加如上配置后,即可放开SpringSecurity的认证限制
总结
以上就是今天要讲的内容,本文简单介绍了SpringDoc整合在SpringBoot项目中的步骤,如果有遗漏,请大家留言,看到后会进行补充
另外,我后面还会再出一期关于SpringDoc中的一些详细注解以及SwaggerUI界面的使用方式,大家如果感兴趣,可以关注我的新文章