Spring Boot 集成原生 Swagger(Springfox)自动生成 API 文档实战:以 spring-boot-demo 的 demo-swagger 为例
【免费下载链接】spring-boot-demo🚀一个用来深入学习并实战 Spring Boot 的项目。项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot-demo
本文以当前仓库
spring-boot-demo中的 demo-swagger 模块为蓝本,完整讲解如何在 Spring Boot 项目中集成 Swagger 2(基于 Springfox 实现),通过注解自动生成、维护并在线调试 RESTful API 文档。读完本文,你将掌握 Swagger 依赖的引入方式、Docket核心配置、Controller 层与实体类的全套注解用法,以及如何通过swagger-ui.html页面实时查看与测试接口。
一、模块概览:为什么要用 Swagger
传统接口文档靠人工维护,接口一变文档就过期,沟通成本高。Swagger 通过注解与代码绑定,让接口文档与源码"同生共死"——只要启动项目,文档即可自动生成、随时可调试。
本 demo 模块(位于 demo-swagger)演示的是 Spring Boot 集成原生 Swagger(即 Springfox 方案),启动后访问:
http://localhost:8080/demo/swagger-ui.html#/即可看到自动生成的 API 文档界面。注意路径中的/demo来自application.yml中配置的server.servlet.context-path(见下文),实际访问地址以你的配置为准。
模块源码结构如下:
demo-swagger/ ├── pom.xml └── src/main/ ├── java/com/xkcoding/swagger/ │ ├── SpringBootDemoSwaggerApplication.java # 启动类 │ ├── common/ # ApiResponse、DataType、ParamType │ ├── config/Swagger2Config.java # Swagger 核心配置 │ ├── controller/UserController.java # API 层注解演示 │ └── entity/User.java # 实体层注解演示 └── resources/application.yml二、引入依赖:springfox-swagger2 + springfox-swagger-ui
在 pom.xml 中,Swagger 相关的依赖只有两个,版本统一由属性swagger.version(2.9.2)控制:
<properties> <java.version>1.8</java.version> <swagger.version>2.9.2</swagger.version> </properties> <dependencies> <!-- Web 基础依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Swagger2 核心,负责扫描注解并生成 JSON 文档(/v2/api-docs) --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <!-- Swagger UI,负责把 JSON 文档渲染成可视化页面(/swagger-ui.html) --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <!-- Lombok,用于简化实体类样板代码(可选) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>要点说明:
springfox-swagger2是核心包,负责扫描注解、收集接口信息并输出 Swagger 规范的 JSON(默认映射到/v2/api-docs);springfox-swagger-ui是可视化界面包,将 JSON 渲染为可交互的 HTML 页面(默认映射到/swagger-ui.html);- 本模块基于 Springfox 2.9.2 与 Java 8、Spring Boot 版本保持一致,属于"原生 Swagger"路线,与仓库中基于
springdoc-openapi的 demo-swagger-beauty 模块(knife4j 美化版)形成对比。
三、基础配置:端口与 context-path
application.yml 中仅做了两项基础配置:
server: port: 8080 servlet: context-path: /demoserver.port=8080:服务端口;server.servlet.context-path=/demo:所有接口统一加/demo前缀,所以 Swagger 页面地址是http://localhost:8080/demo/swagger-ui.html#/,接口地址则为http://localhost:8080/demo/user之类。
启动入口是 SpringBootDemoSwaggerApplication.java,标准@SpringBootApplication引导类;测试类 SpringBootDemoSwaggerApplicationTests.java 通过contextLoads()验证上下文可正常加载。
四、核心配置类:Swagger2Config 与 Docket
Swagger 的所有全局配置都集中在 Swagger2Config.java 中:
@Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.xkcoding.swagger.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("spring-boot-demo") .description("这是一个简单的 Swagger API 演示") .contact(new Contact("Yangkai.Shen", "http://xkcoding.com", "237497819@qq.com")) .version("1.0.0-SNAPSHOT") .build(); } }逐段拆解:
| 配置段 | 代码 | 作用 |
|---|---|---|
| 启用开关 | @EnableSwagger2 | 开启 Swagger 2 文档生成能力 |
| 文档类型 | new Docket(DocumentationType.SWAGGER_2) | 指定生成 Swagger 2.0 规范文档 |
| 文档信息 | .apiInfo(apiInfo()) | 注入页面顶部展示的标题、描述、联系人与版本号 |
| 接口筛选 | .apis(RequestHandlerSelectors.basePackage("com.xkcoding.swagger.controller")) | 只扫描指定包下的 Controller,这是控制文档范围的关键 |
| 路径筛选 | .paths(PathSelectors.any()) | 对扫描到的接口不做路径过滤,全部纳入文档 |
4.1 apiInfo 文档信息
ApiInfoBuilder支持的常用字段:
title:文档标题,显示在页面顶部;description:文档描述;contact:联系人(姓名、个人主页、邮箱),通过new Contact("Yangkai.Shen", "http://xkcoding.com", "237497819@qq.com")设置;version:接口版本号,方便与后端迭代对应。
4.2 控制文档范围的两种方式
RequestHandlerSelectors:按类筛选扫描目标,常用basePackage(...)(按包扫描)、any()(全部)、withClassAnnotation(...)(按类注解,如@RestController)等;PathSelectors:按 URL 路径筛选,常用any()(全部路径)、ant("/user/**")(Ant 风格通配)等。
两者通过select()...build()链式组合,实际项目中常用"包扫描 + 路径过滤"双重约束,只暴露真正需要对外发布的接口。
五、Controller 层注解:把接口"翻译"成文档
UserController.java 完整演示了 API 层的核心注解,覆盖查询、增删改、批量、数组与文件上传等典型场景。
5.1 类级注解 @Api
@RestController @RequestMapping("/user") @Api(tags = "1.0.0-SNAPSHOT", description = "用户管理", value = "用户管理") public class UserController {tags:分组标签,在 UI 上作为接口分组名称展示(建议用业务名,如"用户管理");description/value:接口组描述信息。
5.2 方法级注解 @ApiOperation
@GetMapping @ApiOperation(value = "条件查询(DONE)", notes = "备注") @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", dataType = DataType.STRING, paramType = ParamType.QUERY, defaultValue = "xxx")}) public ApiResponse<User> getByUserName(String username) { ... }value:接口摘要,显示为方法名;notes:详细备注。
5.3 参数注解 @ApiImplicitParam 与 @ApiImplicitParams
单个参数用@ApiImplicitParam,多个参数用@ApiImplicitParams包裹:
@GetMapping("/{id}") @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH)}) public ApiResponse<User> get(@PathVariable Integer id) { ... } @DeleteMapping("/{id}") @ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH) public void delete(@PathVariable Integer id) { ... }属性含义:
name:参数名;value:参数说明;dataType:参数类型,本模块用DataType常量类统一维护(见第七节);paramType:参数位置,本模块用ParamType常量类统一维护(见第七节);defaultValue:默认值,例如上面的defaultValue = "xxx"。
5.4 @RequestBody 场景:无需手写参数注解
对于 POST / PUT 携带请求体的接口,Swagger 能根据实体类自动解析字段,无需(也不应)再写@ApiImplicitParam:
@PostMapping @ApiOperation(value = "添加用户(DONE)") public User post(@RequestBody User user) { ... } @PostMapping("/multipar") @ApiOperation(value = "添加用户(DONE)") public List<User> multipar(@RequestBody List<User> user) { ... } @PostMapping("/array") @ApiOperation(value = "添加用户(DONE)") public User[] array(@RequestBody User[] user) { ... } @PutMapping("/{id}") @ApiOperation(value = "修改用户(DONE)") public void put(@PathVariable Long id, @RequestBody User user) { ... }这段代码同时演示了三种请求体形态:单个对象User、对象集合List<User>、对象数组User[]。如源码注释所述:"如果你不想写@ApiImplicitParam,那么 swagger 也会使用默认的参数名作为描述信息"。
5.5 文件上传场景
@PostMapping("/{id}/file") @ApiOperation(value = "文件上传(DONE)") public String file(@PathVariable Long id, @RequestParam("file") MultipartFile file) { log.info(file.getContentType()); log.info(file.getName()); log.info(file.getOriginalFilename()); return file.getOriginalFilename(); }MultipartFile参数会被 Swagger 自动识别为文件上传控件,同时通过日志打印ContentType、Name、OriginalFilename便于观察上传信息。
六、实体类与通用返回:模型层注解
6.1 通用响应体 ApiResponse
ApiResponse.java 演示了实体类注解,作为所有接口的统一返回结构:
@Data @Builder @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "通用PI接口返回", description = "Common Api Response") public class ApiResponse<T> implements Serializable { private static final long serialVersionUID = -8987146499044811408L; @ApiModelProperty(value = "通用返回状态", required = true) private Integer code; @ApiModelProperty(value = "通用返回信息", required = true) private String message; @ApiModelProperty(value = "通用返回数据", required = true) private T data; }@ApiModel:标注模型类,value为模型名、description为描述;@ApiModelProperty:标注字段,value为字段说明、required = true表示必填;- 配合 Lombok 的
@Builder,Controller 中可用ApiResponse.<User>builder().code(200).message("操作成功").data(user).build()链式构造返回值。
6.2 业务实体 User
User.java 与ApiResponse的注解用法一致:
@Data @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "用户实体", description = "User Entity") public class User implements Serializable { @ApiModelProperty(value = "主键id", required = true) private Integer id; @ApiModelProperty(value = "用户名", required = true) private String name; @ApiModelProperty(value = "工作岗位", required = true) private String job; }@ApiModelProperty常用属性还有example(示例值)、hidden(隐藏字段,常用于密码等敏感信息)、allowEmptyValue等,实际项目中可按需补充。
七、常量类:DataType 与 ParamType
为了让注解书写更规范、避免魔法字符串,模块在 common 包 下定义了两个常量类:
DataType.java 封装@ApiImplicitParam的dataType取值:
public final class DataType { public final static String STRING = "String"; public final static String INT = "int"; public final static String LONG = "long"; public final static String DOUBLE = "double"; public final static String FLOAT = "float"; public final static String BYTE = "byte"; public final static String BOOLEAN = "boolean"; public final static String ARRAY = "array"; public final static String BINARY = "binary"; public final static String DATETIME = "dateTime"; public final static String PASSWORD = "password"; }ParamType.java 封装paramType的取值(参数所在位置):
public final class ParamType { public final static String QUERY = "query"; // 请求参数(QueryString) public final static String HEADER = "header"; // 请求头 public final static String PATH = "path"; // 路径参数(如 /user/{id}) public final static String BODY = "body"; // 请求体 public final static String FORM = "form"; // 表单参数 }引用方式即上一节所见:dataType = DataType.STRING, paramType = ParamType.QUERY。这样即使 Swagger 底层字符串格式变化,也只需改一处常量,同时 IDE 能提供自动补全、降低拼写错误概率。
八、启动与使用
8.1 启动项目
在demo-swagger目录下执行:
mvn spring-boot:run或直接运行 SpringBootDemoSwaggerApplication.java 的main方法。
8.2 访问文档
- 可视化页面:
http://localhost:8080/demo/swagger-ui.html#/ - 原始 JSON 文档:
http://localhost:8080/demo/v2/api-docs(由springfox-swagger2提供,UI 页面即从此端点拉取数据渲染)
在 UI 页面中,可以按@Api的tags分组浏览接口,点击任意接口即可查看参数说明、响应结构,并直接"Try it out"在线调用调试。
8.3 验证文档范围
由于Swagger2Config只扫描com.xkcoding.swagger.controller包,只有该包下的UserController会出现在文档中;如果新增 Controller 但包路径不符,将不会出现在文档里。调整扫描范围即可控制接口的暴露粒度。
九、常用注解速查表
| 注解 | 作用位置 | 用途 |
|---|---|---|
@EnableSwagger2 | 配置类 | 开启 Swagger 2 |
@Api | Controller 类 | 声明接口分组(tags)、描述 |
@ApiOperation | 方法 | 声明接口摘要(value)与备注(notes) |
@ApiImplicitParam | 方法/参数 | 声明单个参数:name、value、dataType、paramType、defaultValue |
@ApiImplicitParams | 方法 | 包裹多个@ApiImplicitParam |
@ApiModel | 实体类 | 声明模型类名称与描述 |
@ApiModelProperty | 实体字段 | 声明字段说明、是否必填、示例值 |
十、小结
通过 demo-swagger 模块可以看到,Spring Boot 集成原生 Swagger(Springfox)只需三步:引入springfox-swagger2与springfox-swagger-ui两个依赖;编写@EnableSwagger2配置类并声明DocketBean 控制扫描范围与文档信息;在 Controller 与实体类上补充@Api、@ApiOperation、@ApiModel等注解。启动后即可获得可交互的在线 API 文档,实现"代码即文档"。
对于更现代、更美观的文档体验,可进一步参考本仓库的 demo-swagger-beauty 模块(基于 knife4j 增强 UI),两者注解体系一脉相承,可以平滑迁移。
【免费下载链接】spring-boot-demo🚀一个用来深入学习并实战 Spring Boot 的项目。项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot-demo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考