活动公告

系统通知
06-22 18:10
系统通知
06-14 00:00
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

深入解析Swagger配置参数描述从入门到精通全面掌握API文档化核心技巧

SunJu_FaceMall

3万

主题

3148

科技点

3万

积分

执行版主

碾压王

积分
32876

塔罗立华奏

执行版主 发表于 2025-9-8 20:10:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

在当今的软件开发领域,API(应用程序编程接口)已经成为不同系统之间通信的桥梁。随着微服务架构的普及,API的数量和复杂性急剧增加,如何有效管理和文档化这些API成为开发者面临的重要挑战。Swagger作为一个强大的API文档化工具,已经成为行业标准,它不仅能够自动生成交互式API文档,还能提供客户端SDK生成和API测试等功能。

本文将深入探讨Swagger的配置参数,从基础概念到高级技巧,帮助读者全面掌握API文档化的核心技能。无论您是刚接触Swagger的新手,还是希望提升使用经验的资深开发者,本文都能为您提供有价值的参考。

1. Swagger基础入门

1.1 Swagger简介与历史

Swagger最初由Tony Tam在2010年创建,旨在解决RESTful API文档化的问题。2015年,Swagger规范被捐赠给Linux基金会,并改名为OpenAPI Specification(OAS)。尽管规范名称更改,但Swagger工具生态系统继续发展,如今已成为API开发领域的重要工具。

Swagger的核心价值在于:

• 自动生成交互式API文档
• 提供API测试界面
• 支持客户端SDK生成
• 标准化API描述格式

1.2 Swagger规范(Swagger Specification)概述

Swagger规范(现称为OpenAPI Specification)是一种RESTful API描述格式,它使用JSON或YAML格式定义API的结构。一个基本的Swagger规范文档包含以下部分:
  1. swagger: "2.0"
  2. info:
  3.   title: 示例API
  4.   description: 这是一个简单的API示例
  5.   version: "1.0.0"
  6. host: api.example.com
  7. basePath: /v1
  8. schemes:
  9.   - https
  10. paths:
  11.   /users:
  12.     get:
  13.       summary: 获取用户列表
  14.       description: 返回系统中的所有用户
  15.       responses:
  16.         200:
  17.           description: 成功响应
  18.           schema:
  19.             type: array
  20.             items:
  21.               $ref: "#/definitions/User"
  22. definitions:
  23.   User:
  24.     type: object
  25.     properties:
  26.       id:
  27.         type: integer
  28.         format: int64
  29.       name:
  30.         type: string
复制代码

1.3 Swagger核心组件介绍

Swagger生态系统包含几个核心组件:

1. Swagger Editor:基于浏览器的编辑器,用于编写OpenAPI规范。
2. Swagger UI:将OpenAPI规范呈现为交互式API文档。
3. Swagger Codegen:根据OpenAPI规范生成服务器存根和客户端SDK。
4. Swagger Parser:用于解析OpenAPI规范的独立库。
5. Swagger Core:Java库,用于创建、消费和使用OpenAPI定义。

2. Swagger配置参数详解

2.1 基础配置参数

在Java项目中,通常使用Springfox或SpringDoc库来集成Swagger。以下是基础配置参数:
  1. @Configuration
  2. @EnableSwagger2
  3. public class SwaggerConfig {
  4.    
  5.     @Bean
  6.     public Docket api() {
  7.         return new Docket(DocumentationType.SWAGGER_2)
  8.                 .select()
  9.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  10.                 .paths(PathSelectors.any())
  11.                 .build()
  12.                 .apiInfo(apiInfo());
  13.     }
  14.    
  15.     private ApiInfo apiInfo() {
  16.         return new ApiInfoBuilder()
  17.                 .title("示例API文档")
  18.                 .description("这是一个使用Springfox创建的API文档示例")
  19.                 .version("1.0.0")
  20.                 .contact(new Contact("开发者名称", "http://example.com", "contact@example.com"))
  21.                 .license("Apache License Version 2.0")
  22.                 .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
  23.                 .build();
  24.     }
  25. }
复制代码
  1. @Configuration
  2. public class SwaggerConfig {
  3.    
  4.     @Bean
  5.     public OpenAPI customOpenAPI() {
  6.         return new OpenAPI()
  7.                 .info(new Info()
  8.                         .title("示例API文档")
  9.                         .version("1.0.0")
  10.                         .description("这是一个使用SpringDoc创建的API文档示例")
  11.                         .contact(new Contact()
  12.                                 .name("开发者名称")
  13.                                 .url("http://example.com")
  14.                                 .email("contact@example.com"))
  15.                         .license(new License()
  16.                                 .name("Apache License Version 2.0")
  17.                                 .url("https://www.apache.org/licenses/LICENSE-2.0")))
  18.                 .externalDocs(new ExternalDocumentation()
  19.                         .description("项目Wiki")
  20.                         .url("https://example.com/wiki"));
  21.     }
  22. }
复制代码

2.2 高级配置参数
  1. @Bean
  2. public Docket api() {
  3.     // 全局响应消息
  4.     List<ResponseMessage> responseMessages = new ArrayList<>();
  5.     responseMessages.add(new ResponseMessageBuilder()
  6.             .code(500)
  7.             .message("服务器错误")
  8.             .responseModel(new ModelRef("Error"))
  9.             .build());
  10.    
  11.     // 全局参数
  12.     ParameterBuilder parameterBuilder = new ParameterBuilder();
  13.     List<Parameter> parameters = new ArrayList<>();
  14.     parameterBuilder.name("token")
  15.             .description("认证令牌")
  16.             .modelRef(new ModelRef("string"))
  17.             .parameterType("header")
  18.             .required(true)
  19.             .build();
  20.     parameters.add(parameterBuilder.build());
  21.    
  22.     return new Docket(DocumentationType.SWAGGER_2)
  23.             .select()
  24.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  25.             .paths(PathSelectors.any())
  26.             .build()
  27.             .globalResponseMessage(RequestMethod.GET, responseMessages)
  28.             .globalOperationParameters(parameters)
  29.             .apiInfo(apiInfo());
  30. }
复制代码
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .securitySchemes(Arrays.asList(apiKey()))
  9.             .securityContexts(Arrays.asList(securityContext()))
  10.             .apiInfo(apiInfo());
  11. }
  12. private ApiKey apiKey() {
  13.     return new ApiKey("JWT", "Authorization", "header");
  14. }
  15. private SecurityContext securityContext() {
  16.     return SecurityContext.builder()
  17.             .securityReferences(defaultAuth())
  18.             .forPaths(PathSelectors.regex("/api/.*"))
  19.             .build();
  20. }
  21. private List<SecurityReference> defaultAuth() {
  22.     AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
  23.     AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
  24.     authorizationScopes[0] = authorizationScope;
  25.     return Arrays.asList(new SecurityReference("JWT", authorizationScopes));
  26. }
复制代码

2.3 自定义配置参数
  1. @Bean
  2. public Docket api() {
  3.     // 自定义响应消息
  4.     List<ResponseMessage> responseMessages = new ArrayList<>();
  5.     responseMessages.add(new ResponseMessageBuilder()
  6.             .code(400)
  7.             .message("错误的请求参数")
  8.             .responseModel(new ModelRef("ErrorResponse"))
  9.             .build());
  10.     responseMessages.add(new ResponseMessageBuilder()
  11.             .code(401)
  12.             .message("未授权访问")
  13.             .responseModel(new ModelRef("ErrorResponse"))
  14.             .build());
  15.     responseMessages.add(new ResponseMessageBuilder()
  16.             .code(404)
  17.             .message("资源不存在")
  18.             .responseModel(new ModelRef("ErrorResponse"))
  19.             .build());
  20.     responseMessages.add(new ResponseMessageBuilder()
  21.             .code(500)
  22.             .message("服务器内部错误")
  23.             .responseModel(new ModelRef("ErrorResponse"))
  24.             .build());
  25.    
  26.     return new Docket(DocumentationType.SWAGGER_2)
  27.             .select()
  28.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  29.             .paths(PathSelectors.any())
  30.             .build()
  31.             .globalResponseMessage(RequestMethod.GET, responseMessages)
  32.             .globalResponseMessage(RequestMethod.POST, responseMessages)
  33.             .globalResponseMessage(RequestMethod.PUT, responseMessages)
  34.             .globalResponseMessage(RequestMethod.DELETE, responseMessages)
  35.             .apiInfo(apiInfo());
  36. }
复制代码
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .additionalModels(typeResolver.resolve(ErrorResponse.class))
  9.             .apiInfo(apiInfo());
  10. }
  11. @ApiModel(description = "错误响应模型")
  12. public class ErrorResponse {
  13.     @ApiModelProperty(value = "错误代码", example = "400")
  14.     private int code;
  15.    
  16.     @ApiModelProperty(value = "错误消息", example = "错误的请求参数")
  17.     private String message;
  18.    
  19.     @ApiModelProperty(value = "错误详情", example = "用户名不能为空")
  20.     private String details;
  21.    
  22.     // getters and setters
  23. }
复制代码

3. Swagger注解使用指南

3.1 核心注解详解

用于标记Controller类,作为Swagger文档资源。
  1. @RestController
  2. @RequestMapping("/api/users")
  3. @Api(tags = "用户管理", description = "提供用户相关的REST API")
  4. public class UserController {
  5.     // ...
  6. }
复制代码

用于标记Controller方法,描述API操作。
  1. @GetMapping("/{id}")
  2. @ApiOperation(value = "获取用户详情", notes = "根据用户ID获取用户的详细信息", response = User.class)
  3. public ResponseEntity<User> getUserById(@PathVariable Long id) {
  4.     // ...
  5. }
复制代码

用于标记方法参数,描述参数信息。
  1. @GetMapping("/search")
  2. @ApiOperation(value = "搜索用户", notes = "根据关键字搜索用户")
  3. public ResponseEntity<List<User>> searchUsers(
  4.         @ApiParam(name = "keyword", value = "搜索关键字", required = true) @RequestParam String keyword,
  5.         @ApiParam(name = "page", value = "页码", defaultValue = "0") @RequestParam(defaultValue = "0") int page,
  6.         @ApiParam(name = "size", value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") int size) {
  7.     // ...
  8. }
复制代码

3.2 模型定义注解

用于标记模型类,提供模型描述。
  1. @ApiModel(description = "用户模型")
  2. public class User {
  3.     // ...
  4. }
复制代码

用于标记模型属性,描述属性信息。
  1. @ApiModel(description = "用户模型")
  2. public class User {
  3.     @ApiModelProperty(value = "用户ID", example = "1", required = true)
  4.     private Long id;
  5.    
  6.     @ApiModelProperty(value = "用户名", example = "john_doe", required = true)
  7.     private String username;
  8.    
  9.     @ApiModelProperty(value = "电子邮箱", example = "john@example.com", required = true)
  10.     private String email;
  11.    
  12.     @ApiModelProperty(value = "创建时间", example = "2023-01-01T00:00:00Z", required = false)
  13.     private Date createdAt;
  14.    
  15.     // getters and setters
  16. }
复制代码

3.3 API操作注解

用于描述API操作的响应。
  1. @GetMapping("/{id}")
  2. @ApiOperation(value = "获取用户详情", notes = "根据用户ID获取用户的详细信息")
  3. @ApiResponses(value = {
  4.     @ApiResponse(code = 200, message = "成功获取用户信息", response = User.class),
  5.     @ApiResponse(code = 404, message = "用户不存在", response = ErrorResponse.class),
  6.     @ApiResponse(code = 500, message = "服务器内部错误", response = ErrorResponse.class)
  7. })
  8. public ResponseEntity<User> getUserById(@PathVariable Long id) {
  9.     // ...
  10. }
复制代码

用于描述非JAX-RS环境的参数。
  1. @PostMapping("/login")
  2. @ApiOperation(value = "用户登录", notes = "使用用户名和密码进行登录")
  3. @ApiImplicitParams({
  4.     @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query"),
  5.     @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query")
  6. })
  7. public ResponseEntity<Token> login(String username, String password) {
  8.     // ...
  9. }
复制代码

4. 集成Swagger到项目

4.1 Spring Boot集成Swagger

对于Springfox(Swagger 2.0):
  1. <dependency>
  2.     <groupId>io.springfox</groupId>
  3.     <artifactId>springfox-swagger2</artifactId>
  4.     <version>3.0.0</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>io.springfox</groupId>
  8.     <artifactId>springfox-swagger-ui</artifactId>
  9.     <version>3.0.0</version>
  10. </dependency>
复制代码

对于SpringDoc(OpenAPI 3.0):
  1. <dependency>
  2.     <groupId>org.springdoc</groupId>
  3.     <artifactId>springdoc-openapi-ui</artifactId>
  4.     <version>1.6.14</version>
  5. </dependency>
复制代码

Springfox配置类:
  1. @Configuration
  2. @EnableSwagger2
  3. public class SwaggerConfig {
  4.    
  5.     @Bean
  6.     public Docket api() {
  7.         return new Docket(DocumentationType.SWAGGER_2)
  8.                 .select()
  9.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  10.                 .paths(PathSelectors.any())
  11.                 .build()
  12.                 .apiInfo(apiInfo());
  13.     }
  14.    
  15.     private ApiInfo apiInfo() {
  16.         return new ApiInfoBuilder()
  17.                 .title("示例API文档")
  18.                 .description("这是一个使用Springfox创建的API文档示例")
  19.                 .version("1.0.0")
  20.                 .contact(new Contact("开发者名称", "http://example.com", "contact@example.com"))
  21.                 .license("Apache License Version 2.0")
  22.                 .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
  23.                 .build();
  24.     }
  25. }
复制代码

SpringDoc配置类:
  1. @Configuration
  2. public class SwaggerConfig {
  3.    
  4.     @Bean
  5.     public OpenAPI customOpenAPI() {
  6.         return new OpenAPI()
  7.                 .info(new Info()
  8.                         .title("示例API文档")
  9.                         .version("1.0.0")
  10.                         .description("这是一个使用SpringDoc创建的API文档示例")
  11.                         .contact(new Contact()
  12.                                 .name("开发者名称")
  13.                                 .url("http://example.com")
  14.                                 .email("contact@example.com"))
  15.                         .license(new License()
  16.                                 .name("Apache License Version 2.0")
  17.                                 .url("https://www.apache.org/licenses/LICENSE-2.0")))
  18.                 .externalDocs(new ExternalDocumentation()
  19.                         .description("项目Wiki")
  20.                         .url("https://example.com/wiki"));
  21.     }
  22. }
复制代码

在Spring Boot主类上添加注解:

Springfox:
  1. @SpringBootApplication
  2. @EnableSwagger2
  3. public class Application {
  4.     public static void main(String[] args) {
  5.         SpringApplication.run(Application.class, args);
  6.     }
  7. }
复制代码

SpringDoc:
  1. @SpringBootApplication
  2. public class Application {
  3.     public static void main(String[] args) {
  4.         SpringApplication.run(Application.class, args);
  5.     }
  6. }
复制代码

4.2 其他框架集成Swagger

首先安装必要的依赖:
  1. npm install swagger-ui-express swagger-jsdoc
复制代码

然后配置Swagger:
  1. const express = require('express');
  2. const swaggerUi = require('swagger-ui-express');
  3. const swaggerJsdoc = require('swagger-jsdoc');
  4. const app = express();
  5. const options = {
  6.   definition: {
  7.     openapi: '3.0.0',
  8.     info: {
  9.       title: '示例API文档',
  10.       version: '1.0.0',
  11.       description: '这是一个使用swagger-jsdoc创建的API文档示例',
  12.     },
  13.     servers: [
  14.       {
  15.         url: 'http://localhost:3000',
  16.       },
  17.     ],
  18.   },
  19.   apis: ['./routes/*.js'], // 包含API注解的文件路径
  20. };
  21. const specs = swaggerJsdoc(options);
  22. app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));
  23. // 路由定义
  24. app.use('/users', require('./routes/users'));
  25. app.listen(3000, () => {
  26.   console.log('服务器运行在 http://localhost:3000');
  27.   console.log('Swagger文档在 http://localhost:3000/api-docs');
  28. });
复制代码

在路由文件中添加Swagger注解:
  1. const express = require('express');
  2. const router = express.Router();
  3. /**
  4. * @swagger
  5. * /users:
  6. *   get:
  7. *     summary: 获取用户列表
  8. *     responses:
  9. *       200:
  10. *         description: 成功响应
  11. *         content:
  12. *           application/json:
  13. *             schema:
  14. *               type: array
  15. *               items:
  16. *                 $ref: '#/components/schemas/User'
  17. */
  18. router.get('/', (req, res) => {
  19.   res.json([
  20.     { id: 1, name: 'John Doe', email: 'john@example.com' },
  21.     { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
  22.   ]);
  23. });
  24. /**
  25. * @swagger
  26. * components:
  27. *   schemas:
  28. *     User:
  29. *       type: object
  30. *       properties:
  31. *         id:
  32. *           type: integer
  33. *           description: 用户ID
  34. *         name:
  35. *           type: string
  36. *           description: 用户名
  37. *         email:
  38. *           type: string
  39. *           description: 电子邮箱
  40. */
  41. module.exports = router;
复制代码

首先安装必要的依赖:
  1. pip install flask-restx
复制代码

然后配置Swagger:
  1. from flask import Flask
  2. from flask_restx import Api, Resource, fields
  3. app = Flask(__name__)
  4. api = Api(app, version='1.0', title='示例API文档',
  5.           description='这是一个使用flask-restx创建的API文档示例')
  6. ns = api.namespace('users', description='用户相关操作')
  7. # 定义用户模型
  8. user_model = api.model('User', {
  9.     'id': fields.Integer(required=True, description='用户ID'),
  10.     'name': fields.String(required=True, description='用户名'),
  11.     'email': fields.String(required=True, description='电子邮箱')
  12. })
  13. @ns.route('/')
  14. class UserList(Resource):
  15.     @ns.doc('list_users')
  16.     @ns.marshal_list_with(user_model)
  17.     def get(self):
  18.         '''获取用户列表'''
  19.         return [
  20.             {'id': 1, 'name': 'John Doe', 'email': 'john@example.com'},
  21.             {'id': 2, 'name': 'Jane Smith', 'email': 'jane@example.com'}
  22.         ]
  23. if __name__ == '__main__':
  24.     app.run(debug=True)
复制代码

5. Swagger UI定制与优化

5.1 UI界面定制

Springfox配置:
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .apiInfo(apiInfo());
  9. }
  10. private ApiInfo apiInfo() {
  11.     return new ApiInfoBuilder()
  12.             .title("自定义API文档")
  13.             .description("这是一个自定义的API文档示例")
  14.             .version("1.0.0")
  15.             .contact(new Contact("开发者名称", "http://example.com", "contact@example.com"))
  16.             .license("Apache License Version 2.0")
  17.             .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
  18.             .build();
  19. }
复制代码

SpringDoc配置:
  1. @Bean
  2. public OpenAPI customOpenAPI() {
  3.     return new OpenAPI()
  4.             .info(new Info()
  5.                     .title("自定义API文档")
  6.                     .version("1.0.0")
  7.                     .description("这是一个自定义的API文档示例")
  8.                     .contact(new Contact()
  9.                             .name("开发者名称")
  10.                             .url("http://example.com")
  11.                             .email("contact@example.com"))
  12.                     .license(new License()
  13.                             .name("Apache License Version 2.0")
  14.                             .url("https://www.apache.org/licenses/LICENSE-2.0")));
  15. }
复制代码

可以通过添加自定义CSS来改变Swagger UI的样式:
  1. @Configuration
  2. public class SwaggerUIConfig implements WebMvcConfigurer {
  3.    
  4.     @Override
  5.     public void addResourceHandlers(ResourceHandlerRegistry registry) {
  6.         registry.addResourceHandler("/swagger-ui/**")
  7.                 .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
  8.                 .resourceChain(false);
  9.     }
  10.    
  11.     @Bean
  12.     public Docket api() {
  13.         return new Docket(DocumentationType.SWAGGER_2)
  14.                 .select()
  15.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  16.                 .paths(PathSelectors.any())
  17.                 .build()
  18.                 .apiInfo(apiInfo());
  19.     }
  20.    
  21.     @Controller
  22.     public static class SwaggerCustomizationController {
  23.         @GetMapping("/swagger-ui.html")
  24.         public String swaggerUi() {
  25.             return "forward:/swagger-ui/index.html";
  26.         }
  27.         
  28.         @GetMapping("/swagger-ui/index.html")
  29.         public String swaggerUiIndex() {
  30.             return "forward:/swagger-ui/index.html";
  31.         }
  32.     }
  33. }
复制代码

在resources/static目录下添加自定义CSS文件custom-swagger.css:
  1. .swagger-ui .topbar {
  2.     display: none;
  3. }
  4. .swagger-ui .info {
  5.     margin: 50px 0;
  6. }
  7. .swagger-ui .info .title {
  8.     color: #3b4151;
  9.     font-family: sans-serif;
  10.     font-size: 36px;
  11. }
  12. .swagger-ui .info .description {
  13.     color: #3b4151;
  14.     font-family: sans-serif;
  15.     font-size: 18px;
  16. }
复制代码

然后在HTML中引用这个CSS文件:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Swagger UI</title>
  6.     <link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
  7.     <link rel="stylesheet" type="text/css" href="./custom-swagger.css" >
  8.     <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
  9.     <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
  10.     <style>
  11.         html
  12.         {
  13.             box-sizing: border-box;
  14.             overflow: -moz-scrollbars-vertical;
  15.             overflow-y: scroll;
  16.         }
  17.         *, *:before, *:after
  18.         {
  19.             box-sizing: inherit;
  20.         }
  21.         body
  22.         {
  23.             margin:0;
  24.             background: #fafafa;
  25.         }
  26.     </style>
  27. </head>
  28. <body>
  29.     <div id="swagger-ui"></div>
  30.     <script src="./swagger-ui-bundle.js"> </script>
  31.     <script src="./swagger-ui-standalone-preset.js"> </script>
  32.     <script>
  33.         window.onload = function() {
  34.             // Build a system
  35.             const ui = SwaggerUIBundle({
  36.                 url: "/v2/api-docs",
  37.                 dom_id: '#swagger-ui',
  38.                 deepLinking: true,
  39.                 presets: [
  40.                     SwaggerUIBundle.presets.apis,
  41.                     SwaggerUIStandalonePreset
  42.                 ],
  43.                 plugins: [
  44.                     SwaggerUIBundle.plugins.DownloadUrl
  45.                 ],
  46.                 layout: "StandaloneLayout"
  47.             });
  48.             window.ui = ui;
  49.         };
  50.     </script>
  51. </body>
  52. </html>
复制代码

5.2 文档展示优化
  1. @Configuration
  2. @EnableSwagger2
  3. public class SwaggerConfig {
  4.    
  5.     @Bean
  6.     public Docket publicApi() {
  7.         return new Docket(DocumentationType.SWAGGER_2)
  8.                 .groupName("public")
  9.                 .select()
  10.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller.public"))
  11.                 .paths(PathSelectors.any())
  12.                 .build()
  13.                 .apiInfo(publicApiInfo());
  14.     }
  15.    
  16.     @Bean
  17.     public Docket privateApi() {
  18.         return new Docket(DocumentationType.SWAGGER_2)
  19.                 .groupName("private")
  20.                 .select()
  21.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller.private"))
  22.                 .paths(PathSelectors.any())
  23.                 .build()
  24.                 .apiInfo(privateApiInfo());
  25.     }
  26.    
  27.     private ApiInfo publicApiInfo() {
  28.         return new ApiInfoBuilder()
  29.                 .title("公共API文档")
  30.                 .description("公共API接口文档")
  31.                 .version("1.0.0")
  32.                 .build();
  33.     }
  34.    
  35.     private ApiInfo privateApiInfo() {
  36.         return new ApiInfoBuilder()
  37.                 .title("私有API文档")
  38.                 .description("私有API接口文档")
  39.                 .version("1.0.0")
  40.                 .build();
  41.     }
  42. }
复制代码
  1. @RestController
  2. @RequestMapping("/api/users")
  3. @Tag(name = "用户管理", description = "提供用户相关的REST API")
  4. public class UserController {
  5.    
  6.     @GetMapping("/{id}")
  7.     @Operation(summary = "获取用户详情", description = "根据用户ID获取用户的详细信息")
  8.     @ApiResponse(responseCode = "200", description = "成功获取用户信息", content = @Content(schema = @Schema(implementation = User.class)))
  9.     @ApiResponse(responseCode = "404", description = "用户不存在", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
  10.     public ResponseEntity<User> getUserById(@PathVariable Long id) {
  11.         // ...
  12.     }
  13.    
  14.     @PostMapping("/")
  15.     @Operation(summary = "创建用户", description = "创建一个新的用户")
  16.     @ApiResponse(responseCode = "201", description = "用户创建成功", content = @Content(schema = @Schema(implementation = User.class)))
  17.     @ApiResponse(responseCode = "400", description = "请求参数错误", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
  18.     public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest request) {
  19.         // ...
  20.     }
  21. }
复制代码

5.3 权限控制与安全
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .securitySchemes(Arrays.asList(new BasicAuth("basicAuth")))
  9.             .securityContexts(Arrays.asList(securityContext()))
  10.             .apiInfo(apiInfo());
  11. }
  12. private SecurityContext securityContext() {
  13.     return SecurityContext.builder()
  14.             .securityReferences(Arrays.asList(new SecurityReference("basicAuth", new AuthorizationScope[0])))
  15.             .forPaths(PathSelectors.regex("/api/.*"))
  16.             .build();
  17. }
复制代码
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .securitySchemes(Arrays.asList(new ApiKey("apiKey", "Authorization", "header")))
  9.             .securityContexts(Arrays.asList(securityContext()))
  10.             .apiInfo(apiInfo());
  11. }
  12. private SecurityContext securityContext() {
  13.     return SecurityContext.builder()
  14.             .securityReferences(Arrays.asList(new SecurityReference("apiKey", new AuthorizationScope[0])))
  15.             .forPaths(PathSelectors.regex("/api/.*"))
  16.             .build();
  17. }
复制代码
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .securitySchemes(Arrays.asList(new OAuth2Definition()
  9.                     .name("oauth2")
  10.                     .grantTypes(Arrays.asList(new ImplicitGrant()
  11.                             .loginEndpoint(new LoginEndpoint("http://localhost:8080/oauth/token"))
  12.                             .tokenName("access_token")))))
  13.             .securityContexts(Arrays.asList(securityContext()))
  14.             .apiInfo(apiInfo());
  15. }
  16. private SecurityContext securityContext() {
  17.     return SecurityContext.builder()
  18.             .securityReferences(Arrays.asList(new SecurityReference("oauth2",
  19.                     new AuthorizationScope[]{new AuthorizationScope("read", "read access"),
  20.                             new AuthorizationScope("write", "write access")})))
  21.             .forPaths(PathSelectors.regex("/api/.*"))
  22.             .build();
  23. }
复制代码

6. 高级技巧与最佳实践

6.1 多版本API文档管理
  1. @Configuration
  2. @EnableSwagger2
  3. public class SwaggerConfig {
  4.    
  5.     @Bean
  6.     public Docket v1Api() {
  7.         return new Docket(DocumentationType.SWAGGER_2)
  8.                 .groupName("v1")
  9.                 .select()
  10.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  11.                 .paths(PathSelectors.ant("/api/v1/**"))
  12.                 .build()
  13.                 .apiInfo(v1ApiInfo());
  14.     }
  15.    
  16.     @Bean
  17.     public Docket v2Api() {
  18.         return new Docket(DocumentationType.SWAGGER_2)
  19.                 .groupName("v2")
  20.                 .select()
  21.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  22.                 .paths(PathSelectors.ant("/api/v2/**"))
  23.                 .build()
  24.                 .apiInfo(v2ApiInfo());
  25.     }
  26.    
  27.     private ApiInfo v1ApiInfo() {
  28.         return new ApiInfoBuilder()
  29.                 .title("API V1文档")
  30.                 .description("API V1接口文档")
  31.                 .version("1.0.0")
  32.                 .build();
  33.     }
  34.    
  35.     private ApiInfo v2ApiInfo() {
  36.         return new ApiInfoBuilder()
  37.                 .title("API V2文档")
  38.                 .description("API V2接口文档")
  39.                 .version("2.0.0")
  40.                 .build();
  41.     }
  42. }
复制代码
  1. @Target({ElementType.METHOD, ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface ApiVersion {
  5.     int value();
  6. }
  7. @Configuration
  8. @EnableSwagger2
  9. public class SwaggerConfig {
  10.    
  11.     @Bean
  12.     public Docket v1Api() {
  13.         return new Docket(DocumentationType.SWAGGER_2)
  14.                 .groupName("v1")
  15.                 .select()
  16.                 .apis(input -> {
  17.                     ApiVersion apiVersion = input.getHandlerMethod().getMethodAnnotation(ApiVersion.class);
  18.                     if (apiVersion != null && apiVersion.value() == 1) {
  19.                         return true;
  20.                     }
  21.                     return false;
  22.                 })
  23.                 .build()
  24.                 .apiInfo(v1ApiInfo());
  25.     }
  26.    
  27.     @Bean
  28.     public Docket v2Api() {
  29.         return new Docket(DocumentationType.SWAGGER_2)
  30.                 .groupName("v2")
  31.                 .select()
  32.                 .apis(input -> {
  33.                     ApiVersion apiVersion = input.getHandlerMethod().getMethodAnnotation(ApiVersion.class);
  34.                     if (apiVersion != null && apiVersion.value() == 2) {
  35.                         return true;
  36.                     }
  37.                     return false;
  38.                 })
  39.                 .build()
  40.                 .apiInfo(v2ApiInfo());
  41.     }
  42.    
  43.     private ApiInfo v1ApiInfo() {
  44.         return new ApiInfoBuilder()
  45.                 .title("API V1文档")
  46.                 .description("API V1接口文档")
  47.                 .version("1.0.0")
  48.                 .build();
  49.     }
  50.    
  51.     private ApiInfo v2ApiInfo() {
  52.         return new ApiInfoBuilder()
  53.                 .title("API V2文档")
  54.                 .description("API V2接口文档")
  55.                 .version("2.0.0")
  56.                 .build();
  57.     }
  58. }
复制代码

6.2 环境特定配置
  1. @Configuration
  2. @Profile({"dev", "test"})
  3. @EnableSwagger2
  4. public class SwaggerConfig {
  5.    
  6.     @Bean
  7.     public Docket api() {
  8.         return new Docket(DocumentationType.SWAGGER_2)
  9.                 .select()
  10.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  11.                 .paths(PathSelectors.any())
  12.                 .build()
  13.                 .apiInfo(apiInfo());
  14.     }
  15.    
  16.     private ApiInfo apiInfo() {
  17.         return new ApiInfoBuilder()
  18.                 .title("开发环境API文档")
  19.                 .description("开发环境API接口文档")
  20.                 .version("1.0.0")
  21.                 .build();
  22.     }
  23. }
复制代码
  1. @Configuration
  2. @EnableSwagger2
  3. @ConditionalOnProperty(name = "swagger.enabled", havingValue = "true")
  4. public class SwaggerConfig {
  5.    
  6.     @Bean
  7.     public Docket api() {
  8.         return new Docket(DocumentationType.SWAGGER_2)
  9.                 .select()
  10.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  11.                 .paths(PathSelectors.any())
  12.                 .build()
  13.                 .apiInfo(apiInfo());
  14.     }
  15.    
  16.     private ApiInfo apiInfo() {
  17.         return new ApiInfoBuilder()
  18.                 .title("API文档")
  19.                 .description("API接口文档")
  20.                 .version("1.0.0")
  21.                 .build();
  22.     }
  23. }
复制代码

6.3 自动化测试集成
  1. @SpringBootTest
  2. @AutoConfigureMockMvc
  3. @AutoConfigureRestDocs(outputDir = "target/snippets")
  4. public class UserControllerTest {
  5.    
  6.     @Autowired
  7.     private MockMvc mockMvc;
  8.    
  9.     @Test
  10.     public void getUserById() throws Exception {
  11.         this.mockMvc.perform(get("/api/users/1")
  12.                 .accept(MediaType.APPLICATION_JSON))
  13.                 .andExpect(status().isOk())
  14.                 .andDo(document("users/get-user-by-id",
  15.                         responseFields(
  16.                                 fieldWithPath("id").description("用户ID"),
  17.                                 fieldWithPath("name").description("用户名"),
  18.                                 fieldWithPath("email").description("电子邮箱")
  19.                         )));
  20.     }
  21.    
  22.     @Test
  23.     public void createUser() throws Exception {
  24.         Map<String, Object> user = new HashMap<>();
  25.         user.put("name", "John Doe");
  26.         user.put("email", "john@example.com");
  27.         
  28.         this.mockMvc.perform(post("/api/users")
  29.                 .contentType(MediaType.APPLICATION_JSON)
  30.                 .content(objectMapper.writeValueAsString(user)))
  31.                 .andExpect(status().isCreated())
  32.                 .andDo(document("users/create-user",
  33.                         requestFields(
  34.                                 fieldWithPath("name").description("用户名"),
  35.                                 fieldWithPath("email").description("电子邮箱")
  36.                         )));
  37.     }
  38. }
复制代码
  1. @Configuration
  2. public class SwaggerDocumentationConfig {
  3.    
  4.     @Bean
  5.     public RestTemplate restTemplate() {
  6.         return new RestTemplate();
  7.     }
  8.    
  9.     @Bean
  10.     public CommandLineRunner generateSwaggerDocumentation(RestTemplate restTemplate) {
  11.         return args -> {
  12.             // 获取Swagger JSON
  13.             String swaggerJson = restTemplate.getForObject("http://localhost:8080/v2/api-docs", String.class);
  14.             
  15.             // 保存到文件
  16.             Files.write(Paths.get("target/swagger.json"), swaggerJson.getBytes());
  17.             
  18.             // 生成HTML文档
  19.             // 可以使用swagger2markup或asciidoctor等工具将Swagger JSON转换为HTML或其他格式
  20.         };
  21.     }
  22. }
复制代码

7. 常见问题与解决方案

7.1 常见配置错误及解决方法

症状:访问Swagger UI页面时出现404错误。

原因:可能是由于Spring Boot的静态资源处理配置问题。

解决方案:
  1. @Configuration
  2. public class WebMvcConfig implements WebMvcConfigurer {
  3.    
  4.     @Override
  5.     public void addResourceHandlers(ResourceHandlerRegistry registry) {
  6.         registry.addResourceHandler("/swagger-ui/**")
  7.                 .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
  8.                 .resourceChain(false);
  9.     }
  10. }
复制代码

症状:Swagger UI页面可以访问,但没有显示API文档。

原因:可能是由于包扫描路径配置错误。

解决方案:
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller")) // 确保这是正确的包路径
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .apiInfo(apiInfo());
  9. }
复制代码

症状:API文档中显示的模型缺少某些属性。

原因:可能是由于模型属性的访问修饰符问题或缺少适当的注解。

解决方案:
  1. @ApiModel(description = "用户模型")
  2. public class User {
  3.     @ApiModelProperty(value = "用户ID", example = "1", required = true)
  4.     private Long id;
  5.    
  6.     @ApiModelProperty(value = "用户名", example = "john_doe", required = true)
  7.     private String username;
  8.    
  9.     @ApiModelProperty(value = "电子邮箱", example = "john@example.com", required = true)
  10.     private String email;
  11.    
  12.     // 确保有getter和setter方法
  13.     public Long getId() {
  14.         return id;
  15.     }
  16.    
  17.     public void setId(Long id) {
  18.         this.id = id;
  19.     }
  20.    
  21.     public String getUsername() {
  22.         return username;
  23.     }
  24.    
  25.     public void setUsername(String username) {
  26.         this.username = username;
  27.     }
  28.    
  29.     public String getEmail() {
  30.         return email;
  31.     }
  32.    
  33.     public void setEmail(String email) {
  34.         this.email = email;
  35.     }
  36. }
复制代码

7.2 性能优化建议
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .enable(true) // 生产环境可以设置为false
  9.             .apiInfo(apiInfo())
  10.             .forCodeGeneration(true);
  11. }
复制代码
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .apiInfo(apiInfo())
  9.             .ignoredParameterTypes(UnsupportedClass.class); // 忽略不需要扫描的类
  10. }
复制代码
  1. @Configuration
  2. @Profile({"dev", "test"})
  3. @EnableSwagger2
  4. public class SwaggerConfig {
  5.    
  6.     @Bean
  7.     public Docket api() {
  8.         return new Docket(DocumentationType.SWAGGER_2)
  9.                 .select()
  10.                 .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  11.                 .paths(PathSelectors.any())
  12.                 .build()
  13.                 .apiInfo(apiInfo());
  14.     }
  15.    
  16.     private ApiInfo apiInfo() {
  17.         return new ApiInfoBuilder()
  18.                 .title("API文档")
  19.                 .description("API接口文档")
  20.                 .version("1.0.0")
  21.                 .build();
  22.     }
  23. }
复制代码

7.3 维护与更新策略
  1. @Bean
  2. public Docket api() {
  3.     return new Docket(DocumentationType.SWAGGER_2)
  4.             .select()
  5.             .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
  6.             .paths(PathSelectors.any())
  7.             .build()
  8.             .apiInfo(new ApiInfoBuilder()
  9.                     .title("API文档")
  10.                     .description("API接口文档")
  11.                     .version(getBuildVersion()) // 从构建信息中获取版本
  12.                     .build());
  13. }
  14. private String getBuildVersion() {
  15.     try {
  16.         return getClass().getPackage().getImplementationVersion();
  17.     } catch (Exception e) {
  18.         return "1.0.0";
  19.     }
  20. }
复制代码
  1. @Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行
  2. public void updateSwaggerDocumentation() {
  3.     try {
  4.         // 获取Swagger JSON
  5.         String swaggerJson = restTemplate.getForObject("http://localhost:8080/v2/api-docs", String.class);
  6.         
  7.         // 保存到文件
  8.         Files.write(Paths.get("target/swagger.json"), swaggerJson.getBytes());
  9.         
  10.         // 生成HTML文档
  11.         generateHtmlDocumentation(swaggerJson);
  12.         
  13.         // 发送通知
  14.         sendDocumentationUpdateNotification();
  15.     } catch (Exception e) {
  16.         logger.error("更新Swagger文档失败", e);
  17.     }
  18. }
复制代码

8. 总结与展望

Swagger作为API文档化的重要工具,极大地简化了API文档的创建和维护工作。通过本文的详细介绍,我们从基础配置到高级技巧,全面探讨了Swagger的使用方法和最佳实践。

主要收获

1. 基础配置:了解了Swagger的核心组件和基本配置方法,能够快速搭建API文档环境。
2. 注解使用:掌握了Swagger注解的使用方法,能够为API提供详细的文档描述。
3. 项目集成:学习了如何在不同框架中集成Swagger,包括Spring Boot、Node.js Express和Python Flask。
4. UI定制:了解了如何定制Swagger UI界面,提供更好的用户体验。
5. 高级技巧:掌握了多版本API文档管理、环境特定配置和自动化测试集成等高级技巧。
6. 问题解决:了解了常见问题的解决方案和性能优化建议。

未来展望

随着API开发的发展,Swagger(OpenAPI)也在不断演进:

1. OpenAPI 3.1:最新的OpenAPI 3.1版本提供了更多的功能和灵活性,包括对JSON Schema的支持。
2. 自动化程度提高:未来的工具将更加自动化,能够从代码中自动生成更准确的API文档。
3. 更好的集成:Swagger将更好地与其他开发工具和平台集成,提供更完整的API开发生态系统。
4. AI辅助:人工智能技术将被用于辅助API文档的生成和维护,提高文档质量和准确性。

最佳实践建议

1. 保持文档更新:API文档应该与代码保持同步,避免文档过时。
2. 提供清晰的描述:为API端点、参数和模型提供清晰、准确的描述。
3. 使用示例:为API请求和响应提供示例,帮助开发者更好地理解API的使用方法。
4. 考虑安全性:在API文档中考虑安全性,避免暴露敏感信息。
5. 定期审查:定期审查API文档,确保其准确性和完整性。

通过遵循这些最佳实践,您可以充分利用Swagger的强大功能,为您的API提供高质量、易于维护的文档,从而提高开发效率和API的可用性。

希望本文能够帮助您深入理解Swagger配置参数,从入门到精通,全面掌握API文档化的核心技巧。无论您是API开发者还是文档编写者,都可以从Swagger的使用中受益,为您的项目提供更好的API文档体验。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则