{"id":47698053,"url":"https://github.com/weimin96/springdoc-plus","last_synced_at":"2026-05-17T06:07:12.617Z","repository":{"id":341715830,"uuid":"1167697463","full_name":"weimin96/SpringDoc-Plus","owner":"weimin96","description":"Knife4j-like project for Spring Boot 4 + springdoc 3, with Gateway aggregation and refactored UI","archived":false,"fork":false,"pushed_at":"2026-05-03T03:52:09.000Z","size":3393,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T05:07:14.007Z","etag":null,"topics":["gateway","openapi3","springboot","springdoc","swagger-ui"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weimin96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T15:28:42.000Z","updated_at":"2026-05-03T03:41:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/weimin96/SpringDoc-Plus","commit_stats":null,"previous_names":["weimin96/springdoc-plus"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/weimin96/SpringDoc-Plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weimin96%2FSpringDoc-Plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weimin96%2FSpringDoc-Plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weimin96%2FSpringDoc-Plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weimin96%2FSpringDoc-Plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weimin96","download_url":"https://codeload.github.com/weimin96/SpringDoc-Plus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weimin96%2FSpringDoc-Plus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33129104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"online","status_checked_at":"2026-05-17T02:00:05.366Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gateway","openapi3","springboot","springdoc","swagger-ui"],"created_at":"2026-04-02T16:47:46.328Z","updated_at":"2026-05-17T06:07:12.611Z","avatar_url":"https://github.com/weimin96.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SpringDoc-Plus\n\n[English README](README.en.md)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./screenshot/hero.svg\" alt=\"SpringDoc-Plus 项目主图\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.weimin96/springdoc-plus.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.weimin96/springdoc-plus)\n[![License](https://img.shields.io/github/license/weimin96/springdoc-plus)](https://github.com/weimin96/springdoc-plus/blob/main/LICENSE)\n[![Coverage Status](https://coveralls.io/repos/github/weimin96/SpringDoc-Plus/badge.svg?branch=main)](https://coveralls.io/github/weimin96/SpringDoc-Plus?branch=main)\n[![Java Version](https://img.shields.io/badge/Java-17-blue)](https://www.oracle.com/java/technologies/downloads/)\n[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-4.0-green)](https://spring.io/projects/spring-boot)\n\n\u003e 由于 Knife4j 长期未适配 Spring Boot 4.x + Jakarta EE，参考其设计思路重新实现，提供适配 **Spring Boot 4.0 + springdoc-openapi 3.x** 的 OpenAPI 文档聚合 UI，支持 Gateway 多服务聚合与单服务两种模式。\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg src=\"./screenshot/overview.png\" width=\"400\"/\u003e\u003cbr/\u003e\n      \u003cstrong\u003e概览\u003c/strong\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg src=\"./screenshot/detail.png\" width=\"400\"/\u003e\u003cbr/\u003e\n      \u003cstrong\u003e接口详情\u003c/strong\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg src=\"./screenshot/setting.png\" width=\"400\"/\u003e\u003cbr/\u003e\n      \u003cstrong\u003e设置\u003c/strong\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg src=\"./screenshot/export.png\" width=\"400\"/\u003e\u003cbr/\u003e\n      \u003cstrong\u003e文档导出\u003c/strong\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## 目录\n\n- [特性](#特性)\n- [技术栈](#技术栈)\n- [模块说明](#模块说明)\n- [快速开始](#快速开始)\n    - [单服务模式](#单服务模式)\n    - [网关聚合模式](#网关聚合模式)\n- [运行 Demo 示例](#运行-demo-示例)\n- [配置参数完整说明](#配置参数完整说明)\n    - [单服务配置](#单服务配置-springdoc-plusopenapi3)\n    - [网关聚合配置](#网关聚合配置-springdoc-plusgateway)\n    - [GatewayRoute 字段](#gatewayroute-字段)\n- [安全认证](#安全认证)\n    - [Basic Auth 保护文档页面](#basic-auth-保护文档页面)\n    - [UI 鉴权透传（Try it out）](#ui-鉴权透传try-it-out)\n- [接口调试](#接口调试)\n- [文档导出](#文档导出)\n- [前端开发](#前端开发)\n- [常见问题](#常见问题)\n- [许可证](#许可证)\n\n---\n\n## 特性\n\n| 功能 | 说明 |\n|------|------|\n| **网关聚合** | 支持 manual（手动配置路由）和 discover（基于服务发现自动聚合）两种模式 |\n| **单服务模式** | 无需网关，单体应用直接使用，支持多分组配置 |\n| **接口调试** | 内置调试面板，支持 path/query/header/cookie 参数，支持 JSON、form-data、multipart 请求体，支持文件上传 |\n| **Basic Auth** | 可选为文档页面开启 HTTP Basic 保护，防止未授权访问，单服务和网关模式均支持 |\n| **UI 鉴权透传** | 全局配置 Bearer Token 或自定义 Header，调试请求自动携带，可持久化到本地存储 |\n| **DOCX 导出** | 一键导出当前服务接口文档为 Word 文档 |\n| **x-order 排序** | 支持通过 `x-order` 扩展字段自定义 Tag / Operation 排序 |\n| **YAML/JSON** | 自动识别 spec 格式，同时支持 JSON 和 YAML |\n| **可分享链接** | 接口详情页 URL 包含定位信息，可直接分享给他人 |\n\n---\n\n## 技术栈\n\n**后端**\n- Java 17\n- Spring Boot 4.0.5\n- Spring Cloud 2025.1.0\n- springdoc-openapi 3.0.3\n\n**前端**（`springdoc-plus-web`）\n- Vue 3.5 + TypeScript 5.9\n- Tailwind CSS v4\n- Vite 7\n\n---\n\n## 模块说明\n\n```\nspringdoc-plus\n├── springdoc-plus-core                          # 共享枚举、模型类（GatewayRoute、UiConfig 等）\n├── springdoc-plus-ui                            # 前端构建产物打包模块（供两个 starter 依赖）\n├── springdoc-plus-web                           # 前端源码（Vue 3 + Tailwind CSS v4）\n├── springdoc-plus-openapi3-spring-boot-starter  # 单服务 starter\n├── springdoc-plus-gateway-spring-boot-starter   # Spring Cloud Gateway 聚合 starter\n└── springdoc-plus-samples                       # 示例工程\n    ├── user-service-sample    (port 8081)\n    ├── order-service-sample   (port 8082)\n    └── gateway-sample         (port 8080)\n```\n\n---\n\n## 快速开始\n\n### 单服务模式\n\n#### 1. 引入依赖\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.weimin96\u003c/groupId\u003e\n    \u003cartifactId\u003espringdoc-plus-openapi3-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.8\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003e 同时确保项目已引入 `springdoc-openapi-starter-webmvc-ui`，该 starter 会自动传递依赖。\n\n#### 2. 启动类添加注解\n\n```java\n@OpenAPIDefinition(info = @Info(title = \"用户服务\", version = \"v1\"))\n@SpringBootApplication\npublic class UserServiceApplication {\n    public static void main(String[] args) {\n        SpringApplication.run(UserServiceApplication.class, args);\n    }\n}\n```\n\n#### 3. 配置（可选）\n\n默认无需任何配置即可使用，以下为完整可选配置项：\n\n```yaml\nspringdoc-plus:\n  openapi3:\n    enabled: true           # 默认 true，设为 false 可整体关闭\n    tags-sorter: order      # Tag 排序策略：alpha（字母序）| order（x-order 值）\n    operations-sorter: order\n\n    # 多分组配置（可选，不配置则使用默认的 /v3/api-docs 单分组）\n    groups:\n      - name: 用户接口\n        url: /v3/api-docs\n        context-path: /\n        order: 1\n      - name: 管理接口\n        url: /v3/api-docs/admin\n        context-path: /\n        order: 2\n\n    # UI 鉴权透传\n    auth:\n      enabled: true\n      header-name: Authorization\n      default-prefix: Bearer\n      persist: true          # 是否保存 Token，UI 内可选择 sessionStorage 或 localStorage\n\n    # HTTP Basic 保护（保护 /doc.html 页面本身）\n    basic:\n      enabled: false\n      username: admin\n      password: \"{bcrypt}$2a$10$...\"\n```\n\n#### 4. 访问\n\n```\nhttp://localhost:8080/doc.html\n```\n\n---\n\n### 网关聚合模式\n\n#### 1. 引入依赖（网关服务）\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.weimin96\u003c/groupId\u003e\n    \u003cartifactId\u003espringdoc-plus-gateway-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.8\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n各下游服务同样需要引入 `springdoc-plus-openapi3-spring-boot-starter` 以暴露 `/v3/api-docs` 接口。\n\n#### 2. 网关配置 —— Manual 模式（推荐生产使用）\n\n手动维护路由列表，配置清晰，不依赖服务注册中心：\n\n```yaml\nspring:\n  cloud:\n    gateway:\n      server:\n        webflux:\n          routes:\n            - id: user-service\n              uri: http://localhost:8081\n              predicates:\n                - Path=/user-service/**\n              filters:\n                - StripPrefix=1\n            - id: order-service\n              uri: http://localhost:8082\n              predicates:\n                - Path=/order-service/**\n              filters:\n                - StripPrefix=1\n\nspringdoc-plus:\n  gateway:\n    enabled: true\n    strategy: manual\n    tags-sorter: order\n    operations-sorter: order\n\n    # Basic Auth 保护文档页面（可选）\n    basic:\n      enabled: false\n      username: admin\n      password: \"{bcrypt}$2a$10$...\"\n\n    # UI 鉴权透传 - 调试接口时自动携带 Token\n    auth:\n      enabled: true\n      header-name: Authorization\n      default-prefix: Bearer\n      persist: true\n\n    routes:\n      - name: 用户服务\n        service-name: user-service\n        url: /user-service/v3/api-docs\n        context-path: /user-service\n        order: 1\n      - name: 订单服务\n        service-name: order-service\n        url: /order-service/v3/api-docs\n        context-path: /order-service\n        order: 2\n```\n\n#### 3. 网关配置 —— Discover 模式（自动聚合）\n\n基于服务发现自动找到所有服务的 API 文档，适合服务数量多且频繁变动的场景：\n\n```yaml\nspringdoc-plus:\n  gateway:\n    enabled: true\n    strategy: discover\n    discover:\n      enabled: true\n      version: openapi3                    # OpenAPI 版本\n      excluded-services:\n        - gateway-sample                   # 排除网关服务自身\n        - config-server                    # 排除其他非业务服务\n      openapi3-url: /v3/api-docs           # 各服务的文档路径（统一）\n      resolve-context-path-from-gateway-routes: true  # 从 Gateway 路由推断 contextPath\n\n      # 对特定服务做个性化配置（可选）\n      service-config:\n        user-service:\n          order: 1\n          group-name: 用户服务\n          context-path: /user-service\n        order-service:\n          order: 2\n          context-path: /order-service\n          group-names:\n            - default\n            - admin     # 该服务有多个分组\n```\n\n\u003e **Discover 模式前置条件：**\n\u003e 1. Gateway 已启用服务发现（`spring.cloud.gateway.discovery.locator.enabled=true`，或配置了 Simple Discovery）\n\u003e 2. 下游服务已注册到注册中心（Nacos、Consul、Eureka、Simple Discovery 等均可）\n\n#### 4. 访问\n\n```\nhttp://localhost:8080/doc.html\n```\n\n---\n\n## 运行 Demo 示例\n\n### 1. 构建整个项目\n\n```bash\nmvn -q verify\n```\n\n### 2. 分别启动三个服务\n\n```bash\n# 终端 1：用户服务（port 8081）\ncd springdoc-plus-samples/user-service-sample\nmvn -q spring-boot:run\n\n# 终端 2：订单服务（port 8082）\ncd springdoc-plus-samples/order-service-sample\nmvn -q spring-boot:run\n\n# 终端 3：网关（port 8080）\ncd springdoc-plus-samples/gateway-sample\nmvn -q spring-boot:run\n```\n\n### 3. 访问地址\n\n| 地址 | 说明 |\n|------|------|\n| `http://localhost:8080/doc.html` | 网关聚合 UI（汇聚用户服务 + 订单服务） |\n| `http://localhost:8081/doc.html` | 用户服务独立 UI |\n| `http://localhost:8082/doc.html` | 订单服务独立 UI |\n\n示例工程默认使用 **manual 模式**，如需切换为 discover 模式，将 `gateway-sample/src/main/resources/application.yml` 中的 `strategy: manual` 改为 `strategy: discover` 即可。\n\n---\n\n## 配置参数完整说明\n\n### 单服务配置（`springdoc-plus.openapi3`）\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | Boolean | `true` | 是否启用单服务文档功能 |\n| `tags-sorter` | `alpha` \\| `order` | `alpha` | Tag 排序策略。`order` 使用 `x-order` 扩展字段 |\n| `operations-sorter` | `alpha` \\| `order` | `alpha` | Operation 排序策略 |\n| `groups[].name` | String | `default` | 分组名称，**不能为空** |\n| `groups[].url` | String | `/v3/api-docs` | 分组对应的 OpenAPI 文档地址，**不能为空** |\n| `groups[].context-path` | String | `/` | 该分组用于调试请求的 basePath |\n| `groups[].order` | Integer | `0` | 分组排序权重，数值越小越靠前 |\n| `auth.enabled` | Boolean | `true` | 是否在 UI 中展示鉴权配置入口 |\n| `auth.header-name` | String | `Authorization` | 鉴权 Header 名称 |\n| `auth.default-prefix` | String | `\"\"` | 鉴权值前缀，如 `Bearer` |\n| `auth.persist` | Boolean | `true` | 是否保存填写的 Token |\n| `basic.enabled` | Boolean | `false` | 是否开启 HTTP Basic 保护文档页面 |\n| `basic.username` | String | — | Basic Auth 用户名（`enabled=true` 时必填） |\n| `basic.password` | String | — | Basic Auth 密码，生产环境建议使用 `{bcrypt}` 前缀哈希值 |\n\n### 网关聚合配置（`springdoc-plus.gateway`）\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | Boolean | `false` | 是否启用网关聚合 |\n| `strategy` | `manual` \\| `discover` | `MANUAL` | 聚合策略 |\n| `tags-sorter` | `alpha` \\| `order` | `alpha` | Tag 排序策略 |\n| `operations-sorter` | `alpha` \\| `order` | `alpha` | Operation 排序策略 |\n| `routes` | List | `[]` | manual 模式的路由列表（见下表） |\n| `discover.enabled` | Boolean | `false` | 是否启用服务发现 |\n| `discover.version` | `openapi3` | `openapi3` | 下游服务的 API 规范版本 |\n| `discover.excluded-services` | Set\\\u003cString\\\u003e | `[]` | 排除的服务名列表（支持精确匹配） |\n| `discover.openapi3-url` | String | `/v3/api-docs` | 各服务统一的文档路径 |\n| `discover.resolve-context-path-from-gateway-routes` | Boolean | `true` | 是否从 Gateway 路由 predicates 自动推断 contextPath |\n| `discover.service-config` | Map | `{}` | 按 serviceId 对特定服务做个性化配置 |\n| `auth.enabled` | Boolean | `true` | 是否启用 UI 鉴权透传 |\n| `auth.header-name` | String | `Authorization` | 鉴权 Header 名称 |\n| `auth.default-prefix` | String | `\"\"` | 鉴权值前缀，如 `Bearer` |\n| `auth.persist` | Boolean | `true` | 是否保存填写的 Token |\n| `basic.enabled` | Boolean | `false` | 是否开启 HTTP Basic 保护文档页面 |\n| `basic.username` | String | — | Basic Auth 用户名 |\n| `basic.password` | String | — | Basic Auth 密码，生产环境建议使用 `{bcrypt}` 前缀哈希值 |\n\n### GatewayRoute 字段\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `name` | String | 是 | 分组在 UI 中的显示名称 |\n| `service-name` | String | 是 | 下游服务名（与 Gateway 路由 id 或服务注册名对应） |\n| `url` | String | 是 | 通过网关访问下游 OpenAPI 文档的路径，如 `/user-service/v3/api-docs` |\n| `context-path` | String | 否 | 调试请求时的 basePath 前缀，通常与 Gateway 路由的 `StripPrefix` 对应，如 `/user-service` |\n| `order` | Integer | 否 | 排序权重，数值越小越靠前，默认 `0` |\n\n---\n\n## 安全认证\n\n### Basic Auth 保护文档页面\n\n两个 starter 均支持用 HTTP Basic 保护 `/doc.html`、`/springdoc-plus-ui/**` 及 `/springdoc-plus-gateway/**` 路径，防止未授权人员访问文档和前端依赖的配置接口。\n\n```yaml\nspringdoc-plus:\n  # 单服务用 openapi3，网关用 gateway\n  openapi3:\n    basic:\n      enabled: true\n      username: admin\n      password: \"{bcrypt}$2a$10$...\"\n```\n\n启用后浏览器会弹出标准 Basic Auth 认证对话框。认证使用恒定时间比对，防止时序攻击。`password` 兼容明文配置，但生产环境应使用 `{bcrypt}` 前缀哈希值，避免将明文密码提交到 Git。\n\n\u003e Basic Auth 以 Base64 明文传输，生产环境请务必配合 HTTPS 使用。可以使用 Spring Security 的 BCrypt 工具生成密码哈希，配置时保留 `{bcrypt}` 前缀。\n\n### UI 鉴权透传（Try it out）\n\n在 UI 右上角\"设置\"中填写 Token，调试接口时会自动将其添加到请求头中，无需每次手动设置。\n\n```yaml\nspringdoc-plus:\n  gateway:\n    auth:\n      enabled: true\n      header-name: Authorization   # 请求头名称\n      default-prefix: Bearer       # 自动拼接前缀，填写 Token 时不需要手动加 \"Bearer \"\n      persist: true                # 是否保存 Token，UI 内可选择 sessionStorage 或 localStorage\n```\n\nToken 保存到 `localStorage` 后会长期保留，若页面存在 XSS 漏洞，Token 可能被窃取。生产环境建议优先选择 `sessionStorage`，只在当前浏览器会话内保留 Token；如必须使用 `localStorage`，应配合严格的内容安全策略、短有效期 Token 与 HTTPS。\n\n### 静态资源路径安全\n\n网关 starter 对 `/springdoc-plus-ui/assets/{filename}`、`/springdoc-plus-ui/docs/{filename}` 与 `/springdoc-plus-ui/{filename}` 只接受单文件名，不允许 `..`、路径分隔符和常见 URL 编码路径片段。对应回归测试覆盖普通路径遍历、反斜杠路径遍历和编码路径遍历，防止通过文档静态资源端点读取受控目录外的 classpath 资源。\n\n---\n\n## 接口调试\n\n接口详情页采用**左右分栏布局**：左侧展示接口文档（参数说明、请求体 Schema、响应文档），右侧固定显示调试面板。\n\n调试面板支持：\n\n| 类型 | 说明 |\n|------|------|\n| **路径参数**（path） | 自动识别 `{id}` 占位符并替换 |\n| **查询参数**（query） | 自动拼接到 URL |\n| **请求头**（header） | 可在调试面板\"请求头\"标签页手动添加 |\n| **JSON 请求体** | 根据 Schema 自动生成示例，支持手动编辑 |\n| **Form 表单**（`application/x-www-form-urlencoded`） | 逐字段填写 |\n| **文件上传**（`multipart/form-data`） | 支持单文件和多文件 |\n| **响应查看** | 展示状态码、响应头、响应体，JSON 自动格式化 |\n\n调试参数和请求体会**自动保存**到本地存储\n\n---\n\n## 文档导出\n\n在 UI 顶部工具栏点击「导出」，可将当前服务的接口文档导出为 **Word（.docx）** 文件，内容包含：\n\n- 服务基本信息（版本、服务地址、联系方式）\n- 按 Tag 分组的接口列表\n- 每个接口的请求参数、请求体 Schema、响应定义\n\n---\n\n## 前端开发\n\n前端源码位于 `springdoc-plus-web/`，基于 Vue 3 + TypeScript + Tailwind CSS v4。\n\n```bash\ncd springdoc-plus-web\npnpm install\n\n# 开发模式（需要后端服务已启动在 8080）\npnpm dev\n\n# 构建前端产物\npnpm run build\n\n# Maven 构建时显式重建前端\ncd ..\nmvn -q -Pfrontend -pl springdoc-plus-ui package\n\n# 构建示例工程\nmvn -q -Psamples package\n\n# 构建并复制产物到 springdoc-plus-ui\npnpm run deploy\n```\n\n---\n\n## 常见问题\n\n**Q: 为什么访问 `/doc.html` 提示 404？**\n\n单服务模式请检查：\n1. `springdoc-plus.openapi3.enabled` 是否为 `true`（默认值即为 true）\n2. classpath 中是否存在 `springdoc-openapi-starter-webmvc-ui`\n\n**Q: 为什么访问 `/doc.html` 时页面空白，浏览器控制台提示 CSS/JS 403 或 MIME type 错误？**\n\n这通常不是前端构建产物损坏，而是业务项目自己的权限配置只放行了 `/doc.html`，没有放行文档页面继续依赖的静态资源和配置接口。  \n\nSpringDoc-Plus 页面加载时还会继续请求：\n- `/springdoc-plus-ui/**`\n- `/springdoc-plus-gateway/**`\n- `/v3/api-docs/**`\n\n如果这些路径被 Spring Security 或其他鉴权拦截器拒绝，浏览器就会出现：\n- `GET /springdoc-plus-ui/assets/*.css 403`\n- `GET /springdoc-plus-ui/assets/*.js 403`\n- `Refused to apply style ... MIME type ('') is not a supported stylesheet MIME type`\n\n建议在业务项目的安全配置中显式放行这些文档相关路径，例如：\n\n```java\n@Bean\npublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {\n    http\n            .authorizeHttpRequests(auth -\u003e auth\n                    .requestMatchers(\n                            \"/doc.html\",\n                            \"/springdoc-plus-ui/**\",\n                            \"/springdoc-plus-gateway/**\",\n                            \"/v3/api-docs/**\"\n                    ).permitAll()\n                    .anyRequest().authenticated()\n            );\n    return http.build();\n}\n```\n\n**Q: 网关聚合后某个服务的接口\"Try it out\"请求失败，提示 CORS 或路径错误？**\n\n检查 `context-path` 配置是否与网关路由的 `StripPrefix` 对应。例如：\n```yaml\n# Gateway 路由\n- Path=/user-service/**\n- StripPrefix=1\n# 则 context-path 应配置为 /user-service\nroutes:\n  - context-path: /user-service\n```\n\n**Q: Discover 模式下某些服务没有出现在文档列表中？**\n\n1. 确认服务已成功注册到注册中心，可通过 `/actuator/gateway/routes` 验证\n2. 检查 `excluded-services` 是否误将该服务排除\n3. 确认该服务暴露了 `springdoc.api-docs.enabled=true` 且路径与 `openapi3-url` 一致\n\n**Q: 如何使用 `x-order` 控制接口排序？**\n\n在 `tags-sorter` / `operations-sorter` 设置为 `order` 后，可以优先使用 `@DocOrder` 简化接口排序：\n\n```java\n@DocOrder(1)\n@GetMapping(\"/users\")\npublic List\u003cUser\u003e users() {\n    return List.of();\n}\n```\n\n也可以继续通过 springdoc 的扩展注解设置排序值：\n\n```java\n@Tag(\n  name = \"用户管理\",\n  extensions = @Extension(properties = @ExtensionProperty(name = \"x-order\", value = \"1\"))\n)\n\n@Operation(\n  summary = \"查询用户\",\n  extensions = @Extension(properties = @ExtensionProperty(name = \"x-order\", value = \"1\"))\n)\n```\n\n**Q: Basic Auth 开启后 Spring Security 会冲突吗？**\n\n不会。`BasicAuthFilter`（单服务）和 `BasicAuthWebFilter`（网关）只拦截文档相关路径（`/doc.html`、`/springdoc-plus-ui/**`、`/springdoc-plus-gateway/**`），不影响业务接口路由，也不依赖 Spring Security。\n\n---\n\n## 许可证\n\n[MIT License](LICENSE)\n\n## 贡献指南\n\n欢迎提交 Issue 和 Pull Request。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweimin96%2Fspringdoc-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweimin96%2Fspringdoc-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweimin96%2Fspringdoc-plus/lists"}