1. 關於Swagger
Swagger 是一個規范和完整的框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務。
相信采用 Spring Boot 開發的小伙伴幾乎是用來構建 RESTful API ,而文檔自然是不可缺少的一部分,Swagger 的出現,既可以減少我們創建文檔的工作量,同時說明內容又整合入實現代碼中,讓維護文檔和修改代碼整合為一體,可以讓我們在修改代碼邏輯的同時方便的修改文檔說明。
另外Swagger2也提供了強大的頁面測試功能來調試每個RESTful API。
作用總結:
- 接口文檔在線生成
- 方便功能測試
集成后的效果圖如下:
2. 開始集成
2.1 添加依賴
在 pom.xml 中添加 swagger 依賴
<!-- Swagger API文檔 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
2.2 配置Swagger
applicaton.yml
# Swagger界面內容配置
swagger:
title: TMax API接口文檔
description: TMax Api Documentation
version: 1.0.0
termsOfServiceUrl: https://www.sscai.club
contact:
name: niceyoo
url: https://www.sscai.club
email: apkdream@163.com
如上配置請置於根節點,如下圖所示:
Swagger2Config.java
新建一個 Swagger2Config.java 的配置類:
- 添加 @Configuration 注解,用於定義配置類,方便被Spring Boot配置;
- 添加 @EnableSwagger2 注解啟動 Swagger 文檔構建能力。
完整代碼如下:
@Slf4j
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Value("${swagger.title}")
private String title;
@Value("${swagger.description}")
private String description;
@Value("${swagger.version}")
private String version;
@Value("${swagger.termsOfServiceUrl}")
private String termsOfServiceUrl;
@Value("${swagger.contact.name}")
private String name;
@Value("${swagger.contact.url}")
private String url;
@Value("${swagger.contact.email}")
private String email;
private List<ApiKey> securitySchemes() {
List<ApiKey> apiKeys = new ArrayList<>();
apiKeys.add(new ApiKey("Authorization", "accessToken", "header"));
return apiKeys;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$")).build());
return securityContexts;
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
@Bean
public Docket createRestApi() {
log.info("加載Swagger2");
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()).select()
## 掃描所有有注解的api,用這種方式更靈活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(title)
.description(description)
.termsOfServiceUrl(termsOfServiceUrl)
.contact(new Contact(name, url, email))
.version(version)
.build();
}
}
方法講解:
通過 createRestfulApiDocs() 方法創建 Docket 的 Bean 之后,apiInfo() 用來創建該 API 的基本信息。(這些基本信息會展現在文檔頁面中,如最開始的預覽圖,增加一些文檔自定義信息)
select() 函數返回一個 ApiSelectorBuilder 實例用來控制哪些接口暴露給Swagger 來展現,本例采用掃描所有帶有 API 注解的對外開放,同時,你也可以采用指定掃描的包路徑來定義,Swagger 則會掃描該包下所有 Controller定義的 API,並產生文檔內容(除了被@ApiIgnore指定的請求)。
如果采用掃描指定包路徑的話,需要修改 createRestApi() 方法的 apis 部分:
.apis(RequestHandlerSelectors.basePackage("com.lemon.security.web.controller"))
2.3 新建entity和controller測試
entity:VideoCategory.java
@Data
@Entity
@Table(name = "v_category")
@TableName("v_category")
@ApiModel(value = "視頻類型")
public class VideoCategory extends TmaxBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "類型名稱")
private String title;
@ApiModelProperty(value = "排序值")
@Column(precision = 10, scale = 2)
private BigDecimal sortOrder;
@ApiModelProperty(value = "是否啟用 0啟用 -1禁用")
private Integer status = CommonConstant.STATUS_NORMAL;
}
controller:VideoCategoryController 主要以添加、查詢為例
@Slf4j
@RestController
@Api(description = "視頻類型管理接口")
@RequestMapping("/tmax/videoCategory")
@Transactional
public class VideoCategoryController extends TmaxBaseController<VideoCategory, String> {
@Autowired
private VideoCategoryService videoCategoryService;
@Override
public VideoCategoryService getService() {
return videoCategoryService;
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ApiOperation(value = "添加")
public Result<Object> add(@ModelAttribute VideoCategory videoCategory){
VideoCategory d = videoCategoryService.save(videoCategory);
return new ResultUtil<Object>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/search", method = RequestMethod.GET)
@ApiOperation(value = "分類名模糊搜索")
public Result<List<VideoCategory>> searchByTitle(
@RequestParam String title,
@ApiParam("是否開始數據權限過濾") @RequestParam(required = false, defaultValue = "true") Boolean openDataFilter){
List<VideoCategory> list = videoCategoryService.findByTitleLikeOrderBySortOrder("%"+title+"%", openDataFilter);
return new ResultUtil<List<VideoCategory>>().setData(list);
}
}
常用注解說明:
- @Api()用於類;
表示標識這個類是swagger的資源 - @ApiOperation()用於方法;
表示一個http請求的操作 - @ApiParam()用於方法,參數,字段說明;
表示對參數的添加元數據(說明或是否必填等) - @ApiModel()用於類
表示對類進行說明,用於參數用實體類接收 - @ApiModelProperty()用於方法,字段
表示對model屬性的說明或者數據操作更改 - @ApiIgnore()用於類,方法,方法參數
表示這個方法或者類被忽略 - @ApiImplicitParam() 用於方法
表示單獨的請求參數 - @ApiImplicitParams() 用於方法,包含多個 @ApiImplicitParam
項目啟動后訪問:http://localhost:端口號(例如8080)/swagger-ui.html
我們嘗試操作一下 add() 方法:
- 填寫實體基本信息
- 點擊 Try it out! 按鈕
3. 最后
在上邊的整個過程中,我們了解 Swagger 除了查看接口功能外,還提供了調試測試功能,點擊“Try it out!”按鈕,即可完成了一次請求調用!
此時,你也可以通過幾個 POST 請求來驗證之前的 POST 請求是否正確。相比為這些接口編寫文檔的工作,我們增加的配置內容是非常少而且精簡的,對於原有代碼的侵入也在忍受范圍之內。
因此,在構建 RESTful API 的同時,加入 Swagger 來對 API 文檔進行管理,是個不錯的選擇。
