現在市面上大多數公司都摒棄了傳統 jsp 開發,采用前后端分離式的開發規則,前端使用 Vue,Angular,React 等等完成頁面,后端省掉了視圖跳轉的過程,直接書寫接口返回 json 數據供前端調用即可
這樣一來就誕生了一個新的問題,后端程序員需要寫一個接口文檔來告訴前端開發人員都有那些接口,每個接口都是干什么的,需要那些參數等等。
書寫接口文檔是一件費時費力的活,而 Swagger 可以根據程序代碼自動生成在線接口文檔,Swagger 是接口文檔生成工具
整合Swagger
教程筆記基於Springboot2.x工程進行測試
導入依賴
想要整合使用 Swagger 生成接口文檔,首先我們需要引用 Swagger 的 maven 依賴:
<!-- 位於io.springfox下的依賴 -->
<dependency> <!-- Swagger的注解依賴包 -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency> <!-- Swagger接口文檔頁面包 -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
實際測試運行時程序會拋出For input string: ""
異常,但是並不會影響運行,這里針對異常可以選擇這樣導包:
<!-- Swagger依賴 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<!-- 排除下面兩個依賴,解決 For input string: "" 異常 -->
<exclusions>
<exclusion>
<groupId>io.springfox</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 單獨引用版本偏低的兩個依賴 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<!-- UI頁面展示 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
啟用Swagger
在引用 Swagger 的依賴后,我們還需要通過注解開啟 Swagge 才可以實現接口文檔
新建一個配置類,通過
@EnableSwagger2
注解啟用 Swagger:
@Configuration
@EnableSwagger2 // 開啟Swagger
public class SwaggerConfig { }
開啟Swagger
后啟動程序,訪問http://localhost:8080/swagger-ui.html
即可看到接口文檔頁面
了解接口文檔
Swagger 接口文檔主要有四部分組成:分組信息
、分組描述信息
、接口描述信息
、實體類信息
我們目前僅僅是引入了 Swagger 的依賴,開啟 Swagger 功能之后如果沒有配置的話,默認會使用 swagger 初始化的配置
初始化分組
我們想要使用自定義的分組信息,要在配置類提供一個 Docket 實例到 IOC 容器中,通過 Docket 實例設置分組名稱,Swagger 會根據實例進行自定義設置。
創建一個分組
// 還是之前的配置類
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("張涵哲的分組");
}
}
上面使用 Swagger2 默認規則創建了一個 Docket 對象,定義分組名稱為 張涵哲的分組
,效果如圖所示:
多分組配置
如果想要創建多個分組,那么就在 IOC 容器中多提供幾個 docket 實例:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("張涵哲的分組");
}
@Bean
public Docket docket1() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("***的分組");
}
}
配置分組詳情
配置分組描述
我們已經可以創建多個分組了,但是我們可以發現,每個分組中都有一段描述信息,我們可以在每個分組下顯示不同的描述信息,需要調用 Docket 的 apiInfo()
函數傳入自定義的配置。
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("張涵哲的分組")
.apiInfo(apiInfo());
}
// 創建一個函數用來返回 ApiInfo 實例
// 這里我只顯示了部分信息,填寫null的都是不顯示的,如果想要全部顯示可以填寫所有的信息
public ApiInfo apiInfo() {
Contact contact = new Contact("張涵哲", "http://blog.hanzhe.club", null);
return new ApiInfo(
"基於Swagger2.0練習",
"基於程序中所有的接口提供幫助文檔",
"1.0.0",
null,
contact,
null,
null,
new ArrayList());
}
}
我們為 張涵哲的分組
配置了一段描述信息,接下來看看效果:
可以看到分組的描述信息已經顯示出來了。
配置掃描范圍
當我們多個人同時開發一個程序時,就會使用多個分組,每個人對應這一個分組,其中每個分組都有自己的接口文檔,這里需要配置分組接口顯示
例:張涵哲負責開發用戶相關的接口 包位置:club.hanzhe.controller.user.UserController.java
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("張涵哲的分組")
.apiInfo(apiInfo())
// select開始,build結束,apis用來過濾
.select()
.apis(RequestHandlerSelectors.basePackage("club.hanzhe.controller.user"))
.build();
}
這樣一來該分組下就只會顯示固定的接口信息了,除開通過包掃描的方法之外還有其他的方法進行篩選:
RequestHandlerSelectors
類中其他的靜態函數:
函數名 | 作用 |
---|---|
any() | 掃描全部接口 |
none() | 不掃描 |
basePackage(String package) | 根據給定的包的位置進行掃描 |
withClassAnnotation(Class annotation) | 類上有對應注解會被掃描 |
withMethodAnnotation(Class annotation) | 函數上有對應注解的會被掃描 |
還可以通過路徑進行過濾:
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("張涵哲的分組")
.apiInfo(apiInfo())
// select開始,build結束,paths用來過濾
.select()
.paths(PathSelectors.ant("/user/**"))
.build();
}
PathSelectors
類中其他的靜態函數:
函數名 | 作用 |
---|---|
any() | 掃描全部接口 |
none() | 不掃描 |
ant(String path) | 掃描指定路徑 |
regex(String regex) | 根據正則表達式過濾 |
接口信息配置
簡單接口顯示
上面的圖片是掃描到接口后默認生成的接口文檔,Swagger 是以 Controller
為單位,對接口進行分組管理的,這個分組的元素在 Swagger 中稱為 Tag
,我們可以通過注解來修改一下接口文檔,讓他更人性化:
注解 | 作用 |
---|---|
@Api(tags = "") | 標注在類上 用來表明接口組,tags=組名 |
@ApiOperation(value = "", notes = "", tags="") | 標注在函數上 value=標題,notes=描述,tags=分組 |
@ApiParam("") | 標注在參數列表中 表示當前參數代表的含義以及用法 |
例如下面我們編輯一下當前的 UserController:
@Api(tags = "User接口文檔")
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/")
@ApiOperation("查詢所有user")
public R getList(){ ... }
@PostMapping("/")
@ApiOperation(value = "添加新的user信息", notes = "傳入用戶信息進行封裝user進行添加")
public R addUser(@RequestBody UserBean user){ ... }
@PutMapping("/{id}")
@ApiOperation(value = "通過ID更新user信息", notes = "路徑傳入ID,json傳輸修改信息")
public R updateUser(@PathVariable("id")Long id, @RequestBody UserBean user){
...
}
@DeleteMapping("/{id}")
@ApiOperation(value = "通過ID刪除user信息", notes = "路徑傳入ID進行刪除")
public R deleteUser(@ApiParam("刪除的目標ID")@PathVariable("id") Long id){
...
}
}
效果如下圖所示:
跨組顯示接口
之前有說過,Swagger 默認是按照每個 Controller 為一個分組顯示接口的,那么如果我們其中一個 Controlle 執行時需要另個 Controller 的某個接口配合,這時我們當前分組就要支持顯示其他分組信息。
**1. **員工的分組接口除了本身的增刪改查之外還要查詢攜帶查詢所有部門信息:
@Api(tags = "部門接口")
@RestController
@RequestMapping("/dept")
public class DeptController {
@GetMapping("/") // tags 是一個數組,可以制定多個分組同時顯示
@ApiOperation( value = "查詢所有部門", tags = {"部門接口", "員工接口"})
public void getList(){ }
// .... 省略其他接口
}
如下圖所示:
通過已有的接口新建一個分組
除了接口跨分組顯示之外,還可以在多個不同的接口中指向同一個不存在的分組,Swagger 會新建一個分組來展示這些接口信息。
@Api(tags = "員工接口")
@RestController
@RequestMapping("/user")
public class UserController {
@DeleteMapping("/{id}")
@ApiOperation(value = "通過ID刪除user信息",
notes = "路徑傳入ID進行刪除", tags = "刪除操作相關接口")
public R deleteUser(@ApiParam("刪除的目標ID")@PathVariable("id") Long id){
...
}
}
@Api(tags = "部門接口")
@RestController
@RequestMapping("/dept")
public class DeptController {
@DeleteMapping("/{id}")
@ApiOperation(value = "通過ID刪除部門", tags = "刪除操作相關接口")
public void deleteUser(@ApiParam("刪除的目標ID")@PathVariable("id") Long id){ }
}
實體類信息配置
我們在開始的時候就 Swagger 接口文檔由 分組
,分組描述信息
,接口信息
,實體類信息
四部分組成,前三種我們已經使用過了,接下來我們就要學習使用配置類信息
當我們需要完成類似添加操作的時候,如果需要的參數過多,使用 @ApiParam 注解就會太過臃腫,直接封裝為實體類又要解釋每個字段都是干什么的,是什么類型,接口顯示也過於繁瑣,所以我們可以將實體類直接顯示在文檔中,當時用到該實體類時在底部翻找屬性對應參數即可,一個實體類可以對應 N 多個接口,一勞永逸
實體類的配置
配置實體類十分的簡單,只需要使用兩個注解就可以完成基本操作:
注解 | 作用 |
---|---|
@ApiModel() | 實體類名稱 |
@ApiModelProperty() | 實體類中每個字段代表的含義解釋 |
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("員工實體類")
public class UserBean {
@ApiModelProperty("員工ID,用來識別員工的唯一表示,不可重復。")
private Long id;
@ApiModelProperty("員工姓名")
private String name;
@ApiModelProperty("員工年齡")
private Integer age;
}
效果如圖所示: