目錄
- 前言:什麼是Swagger
- 起步:(只需簡單的3步)
- 載入依賴
- 添加註解@EnableOpenApi
- 啟動SpringBoot,訪問Swagger後臺介面
- 配置:基於Java的配置
- 註解:Swagger2 和 Swagger3做對比
- 原始碼:https://github.com/Jalon2015/spring-boot-demo/tree/master/demo-swagger3
- 問題:踩坑記錄(後面再整理)
前言
什麼是Swagger:
Swagger 是最流行的 API 開發工具,它遵循 OpenAPI Specification(OpenAPI 規範,也簡稱 OAS)。
它最方便的地方就在於,API文件可以和服務端保持同步,即服務端更新一個介面,前端的API文件就可以實時更新,而且可以線上測試。
這樣一來,Swagger就大大降低了前後端的溝通障礙,不用因為一個介面調不通而爭論不休
之前用的看雲文件,不過這種第三方的都需要手動維護,還是不太方便
起步
- 載入依賴
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
- 新增@EnableOpenApi註解
@EnableOpenApi
@SpringBootApplication
public class SwaggerApplication {
public static void main(String[] args) {
SpringApplication.run(SwaggerApplication.class, args);
}
}
這樣一個簡單的Swagger後臺介面文件就搭建完成了;
下面我們說下配置和註解
配置
可以看到,上面那個介面中,預設顯示了一個basic-error-controller
介面分組,但是我們並沒有寫;
通過在專案中查詢我們發現,SpringBoot內部確實有這樣一個控制器類,如下所示:
這說明Swagger預設的配置,會自動把@Controller控制器類新增到介面文件中
下面我們就自己配置一下,如下所示:
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
// 配置OAS 3.0協議
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
// 查詢有@Tag註解的類,並生成一個對應的分組;類下面的所有http請求方法,都會生成對應的API介面
// 通過這個配置,就可以將那些沒有新增@Tag註解的控制器類排除掉
.apis(RequestHandlerSelectors.withClassAnnotation(Tag.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("GPS Doc")
.description("GPS Doc文件")
.termsOfServiceUrl("http://www.javalover.com")
.contact(new Contact("javalover", "http://www.javalover.cn", "[email protected]"))
.version("2.0.0")
.build();
}
}
這樣上面那個basic-error-controller
就看不見了
註解
我們先看下Swagger2中的註解,如下所示:
@Api:用在控制器類上,表示對類的說明
- tags="說明該類的作用,可以在UI介面上看到的說明資訊的一個好用註解"
- value="該引數沒什麼意義,在UI介面上也看到,所以不需要配置"
@ApiOperation:用在請求的方法上,說明方法的用途、作用
- value="說明方法的用途、作用"
- notes="方法的備註說明"
@ApiImplicitParams:用在請求的方法上,表示一組引數說明
- @ApiImplicitParam:用在@ApiImplicitParams註解中,指定一個請求引數的各個方面(標註一個指定的引數,詳細概括引數的各個方面,例如:引數名是什麼?引數意義,是否必填等)
- name:屬性值為方法引數名
- value:引數意義的漢字說明、解釋
- required:引數是否必須傳
- paramType:引數放在哪個地方
- header --> 請求引數的獲取:@RequestHeader
- query --> 請求引數的獲取:@RequestParam
- path(用於restful介面)--> 請求引數的獲取:@PathVariable
- dataType:引數型別,預設String,其它值dataType="Integer"
- defaultValue:引數的預設值
- @ApiImplicitParam:用在@ApiImplicitParams註解中,指定一個請求引數的各個方面(標註一個指定的引數,詳細概括引數的各個方面,例如:引數名是什麼?引數意義,是否必填等)
@ApiResponses:用在請求的方法上,表示一組響應
- @ApiResponse:用在@ApiResponses中,一般用於表達一個錯誤的響應資訊
- code:狀態碼數字,例如400
- message:資訊,例如"請求引數沒填好"
- response:丟擲異常的類
- @ApiResponse:用在@ApiResponses中,一般用於表達一個錯誤的響應資訊
@ApiModel:用於響應類上(POJO實體類),描述一個返回響應資料的資訊(描述POJO類請求或響應的實體說明)
(這種一般用在post介面的時候,使用@RequestBody接收JSON格式的資料的場景,請求引數無法使用@ApiImplicitParam註解進行描述的時候)- @ApiModelProperty:用在POJO屬性上,描述響應類的屬性說明
@ApiIgnore:使用該註解忽略這個某個API或者引數;
上面這些是Swagger2的註解,下面我們看下Swagger3和它的簡單對比
接下來我們就用Swagger3的註解來寫一個介面看下效果(其中穿插了Swagger2的註解)
- 控制器UserController.java
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@Tag(name = "user-controller", description = "使用者介面")
@RestController
public class UserController {
// 忽略這個api
@Operation(hidden = true)
@GetMapping("/hello")
public String hello(){
return "hello";
}
@Operation(summary = "使用者介面 - 獲取使用者詳情")
@GetMapping("/user/detail")
// 這裡的@Parameter也可以不加,Swagger會自動識別到這個name引數
// 但是加@Parameter註解可以增加一些描述等有用的資訊
public User getUser(@Parameter(in = ParameterIn.QUERY, name = "name", description = "使用者名稱") String name){
User user = new User();
user.setUsername(name);
user.setPassword("123");
return user;
}
@Operation(summary = "使用者介面 - 新增使用者")
@PostMapping("/user/add")
// 這裡的user會被Swagger自動識別
public User addUser(@RequestBody User user){
System.out.println("新增使用者");
return user;
}
}
實體類User.java:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema
@Data
public class User {
@Schema(name = "username", description = "使用者名稱", example = "javalover")
private String username;
@Schema(name = "password", description = "密碼", example = "123456")
private String password;
// 隱藏這個屬性,這樣介面文件的請求引數中就看不到這個屬性
@Schema(hidden = true)
private String email;
}
啟動後執行介面如下:
- 首頁展示:
- /user/add介面展示:
/user/detail介面展示
原始碼
整理在Github上:https://github.com/Jalon2015/spring-boot-demo/tree/master/demo-swagger3
問題
目前只是簡單地體驗了下,其實裡面還是有很多坑,等後面有空再整理解決,下面列舉幾個:
- @Paramters引數無效
- @ApiImplicitParamter的body屬性無效
- @Tag的name屬性:如果name屬性不是當前類名的小寫連字元格式,則會被識別為一個單獨的介面分組
- 等等
最近整理了一份面試資料《Java面試題-校招版》附答案,無密碼無水印,感興趣的可以關注公眾號回覆“面試”領取。