2026/9/3 6:59:44

Swagger 扩展学习:从基础配置到高级定制

Swagger 扩展学习:从基础配置到高级定制 1. 引言Swagger 作为 RESTful API 文档生成工具在前后端分离开发中扮演着重要角色。它不仅能自动生成接口文档还能提供在线调试能力。然而在实际项目中默认的 Swagger 配置往往无法满足复杂业务需求这就需要我们深入学习 Swagger 的扩展机制。本文将从基础配置入手逐步深入到注解扩展、文档定制、安全认证等高级主题帮助读者全面掌握 Swagger 的扩展开发技巧。2. Swagger 基础配置在开始扩展之前我们先回顾 Swagger 的基础配置方式。以 Spring Boot 项目为例首先需要引入相关依赖。dependency groupIdio.springfox/groupId artifactIdspringfox-swagger2/artifactId version2.9.2/version /dependency dependency groupIdio.springfox/groupId artifactIdspringfox-swagger-ui/artifactId version2.9.2/version /dependency接着创建 Swagger 配置类通过 Docket 对象进行基础配置。Configuration EnableSwagger2 public class SwaggerConfig { Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage(com.example.controller)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(用户服务 API) .description(用户管理相关接口文档) .version(1.0.0) .build(); } }3. 常用注解详解Swagger 提供了一系列注解用于增强接口文档的描述信息。下面逐一介绍最常用的几个注解。3.1 Api 注解Api 注解作用于类上用于描述整个 Controller 的功能。Api(tags 用户管理, description 用户增删改查接口) RestController RequestMapping(/api/users) public class UserController { ApiOperation(value 获取用户列表, notes 分页查询用户信息) GetMapping public ResultPageResultUserVO list( ApiParam(value 页码, defaultValue 1) RequestParam int page, ApiParam(value 每页条数, defaultValue 10) RequestParam int size) { return userService.list(page, size); } }3.2 ApiModel 与 ApiModelProperty这两个注解用于描述请求和响应的数据模型。ApiModel(value 用户实体, description 用户信息) public class UserVO { ApiModelProperty(value 用户ID, example 1001) private Long id; ApiModelProperty(value 用户名, example zhangsan) private String username; ApiModelProperty(value 邮箱, example zhangsanexample.com) private String email; ApiModelProperty(value 创建时间, example 2024-01-01 10:00:00) private LocalDateTime createTime; // getter / setter 省略 }3.3 ApiImplicitParams 与 ApiImplicitParam当接口参数无法通过实体类描述时可以使用隐式参数注解。ApiOperation(value 根据条件搜索用户) ApiImplicitParams({ ApiImplicitParam(name keyword, value 搜索关键字, required false, dataType String, paramType query), ApiImplicitParam(name status, value 用户状态, required false, dataType Integer, paramType query) }) GetMapping(/search) public ResultListUserVO search( RequestParam(required false) String keyword, RequestParam(required false) Integer status) { return userService.search(keyword, status); }4. 自定义扩展注解当内置注解无法满足业务需求时我们可以创建自定义注解并通过 Swagger 的扩展点将其集成到文档生成流程中。4.1 创建自定义注解Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface ApiVersion { String value() default v1; String group() default default; }4.2 通过 OperationBuilderPlugin 扩展Swagger 提供了 OperationBuilderPlugin 扩展接口允许我们在构建 Operation 时注入自定义信息。Component public class ApiVersionPlugin implements OperationBuilderPlugin { Override public void apply(OperationContext context) { OptionalApiVersion apiVersion context.findAnnotation(ApiVersion.class); if (apiVersion.isPresent()) { String version apiVersion.get().value(); context.operationBuilder() .summary(context.getOperationBuilder().build().getSummary() [版本: version ]); } } Override public boolean supports(DocumentationType delimiter) { return true; } }4.3 在 Controller 中使用自定义注解ApiOperation(value 获取用户详情) ApiVersion(value v2, group user) GetMapping(/{id}) public ResultUserVO detail(PathVariable Long id) { return userService.detail(id); }5. 文档分组与多环境配置在大型项目中通常需要按模块或版本对接口进行分组同时还要区分不同环境的配置。5.1 多 Docket 分组Configuration EnableSwagger2 public class MultiGroupSwaggerConfig { Bean public Docket userApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName(用户服务) .apiInfo(apiInfo(用户服务 API, 1.0.0)) .select() .apis(RequestHandlerSelectors.basePackage(com.example.controller.user)) .paths(PathSelectors.any()) .build(); } Bean public Docket orderApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName(订单服务) .apiInfo(apiInfo(订单服务 API, 1.0.0)) .select() .apis(RequestHandlerSelectors.basePackage(com.example.controller.order)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo(String title, String version) { return new ApiInfoBuilder() .title(title) .version(version) .build(); } }5.2 环境隔离配置通过 Spring Profile 实现不同环境启用或禁用 Swagger。Configuration EnableSwagger2 Profile({dev, test}) public class SwaggerDevConfig { Bean public Docket devApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(开发环境 API 文档) .version(1.0.0) .build(); } }在生产环境中通过配置类禁用 Swagger。Configuration Profile(prod) public class SwaggerProdConfig { Bean public Docket prodApi() { return new Docket(DocumentationType.SWAGGER_2) .enable(false) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } }6. 安全认证集成当接口需要登录认证时Swagger 文档也需要支持携带 Token 进行调试。通过 ApiKey 和 SecurityContext 实现。Configuration EnableSwagger2 public class SwaggerSecurityConfig { Bean public Docket securedApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage(com.example.controller)) .paths(PathSelectors.any()) .build() .securitySchemes(Collections.singletonList(apiKey())) .securityContexts(Collections.singletonList(securityContext())); } private ApiKey apiKey() { return new ApiKey(Authorization, Authorization, header); } private SecurityContext securityContext() { return SecurityContext.builder() .securityReferences(Collections.singletonList(defaultAuth())) .forPaths(PathSelectors.regex(^(?!/auth/).*)) .build(); } private SecurityReference defaultAuth() { AuthorizationScope authorizationScope new AuthorizationScope(global, accessEverything); AuthorizationScope[] authorizationScopes new AuthorizationScope[1]; authorizationScopes[0] authorizationScope; return new SecurityReference(Authorization, authorizationScopes); } }7. 全局参数与响应处理在实际项目中很多接口需要携带公共参数如请求 ID、用户 Token 等。Swagger 支持配置全局参数。Bean public Docket globalParamApi() { ListParameter globalParams new ArrayList(); ParameterBuilder tokenParam new ParameterBuilder(); tokenParam.name(X-Token) .description(用户认证令牌) .modelRef(new ModelRef(string)) .parameterType(header) .required(false) .build(); globalParams.add(tokenParam.build()); ParameterBuilder requestIdParam new ParameterBuilder(); requestIdParam.name(X-Request-Id) .description(请求追踪ID) .modelRef(new ModelRef(string)) .parameterType(header) .required(false) .build(); globalParams.add(requestIdParam.build()); return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .globalOperationParameters(globalParams) .select() .apis(RequestHandlerSelectors.basePackage(com.example.controller)) .paths(PathSelectors.any()) .build(); }对于统一响应结构可以通过泛型封装并在文档中清晰展示。ApiModel(value 统一响应结构) public class ResultT { ApiModelProperty(value 状态码, example 200) private int code; ApiModelProperty(value 提示信息, example 操作成功) private String message; ApiModelProperty(value 响应数据) private T data; public static T ResultT success(T data) { ResultT result new Result(); result.code 200; result.message 操作成功; result.data data; return result; } public static T ResultT error(int code, String message) { ResultT result new Result(); result.code code; result.message message; return result; } // getter / setter 省略 }8. 自定义 Swagger UI 增强Swagger UI 支持通过配置项进行定制例如修改页面标题、排序规则、默认展开状态等。springfox: documentation: swagger: v2: path: /api-docs ui: title: 企业级 API 文档中心 doc-expansion: list operations-sorter: alpha tags-sorter: alpha display-request-duration: true show-extensions: true validator-url: 如果需要更深入的定制可以通过注入 SwaggerResourcesProvider 实现多文档源聚合。Component public class CustomSwaggerResourcesProvider implements SwaggerResourcesProvider { Override public ListSwaggerResource get() { ListSwaggerResource resources new ArrayList(); SwaggerResource userResource new SwaggerResource(); userResource.setName(用户服务); userResource.setLocation(/api-docs/user); userResource.setSwaggerVersion(2.0); resources.add(userResource); SwaggerResource orderResource new SwaggerResource(); orderResource.setName(订单服务); orderResource.setLocation(/api-docs/order); orderResource.setSwaggerVersion(2.0); resources.add(orderResource); return resources; } }9. 常见问题与最佳实践9.1 常见问题在实际使用中开发者常遇到以下几类问题接口不显示通常是包扫描路径配置错误或 Controller 未添加 Api 注解。参数描述丢失实体类未添加 ApiModelProperty 注解或使用了 final 字段导致反射失败。文档加载缓慢接口数量过多时建议按模块拆分 Docket 分组。生产环境泄露务必通过 Profile 或配置开关在生产环境禁用 Swagger。9.2 最佳实践结合项目经验推荐以下实践方式统一使用 Result 泛型封装响应配合 ApiModel 描述字段含义。为每个 Controller 添加 Api 注解并写明 tags 和 description。敏感接口使用 ApiIgnore 注解排除出文档。在 CI/CD 流程中增加文档校验步骤确保接口变更同步更新文档。ApiIgnore GetMapping(/internal/health) public String healthCheck() { return OK; }10. 总结Swagger 的扩展能力非常强大从基础的注解配置到自定义插件再到多环境管理和安全认证集成都能满足企业级项目的需求。掌握这些扩展技巧可以显著提升 API 文档的质量和维护效率。建议读者在实际项目中循序渐进地应用这些扩展点先完善基础注解再根据业务需要引入自定义插件最后结合团队规范统一文档风格。希望本文能帮助你在 Swagger 扩展学习的道路上少走弯路。