在團隊開發中,一個好的 API 文檔不但可以減少大量的溝通成本,還可以幫助一位新人快速上手業務。傳統的做法是由開發人員創建一份 RESTful API 文檔來記錄所有的接口細節,並在程序員之間代代相傳。
這種做法存在以下幾個問題:
- API 接口衆多,細節複雜,需要考慮不同的HTTP請求類型、HTTP頭部信息、HTTP請求內容等,想要高質量的完成這份文檔需要耗費大量的精力;
- 難以維護。隨着需求的變更和項目的優化、推進,接口的細節在不斷地演變,接口描述文檔也需要同步修訂,可是文檔和代碼處於兩個不同的媒介,除非有嚴格的管理機制,否則很容易出現文檔、接口不一致的情況
Swagger2 的出現就是爲了從根本上解決上述問題。它作爲一個規範和完整的框架,可以用於生成、描述、調用和可視化 RESTful 風格的 Web 服務:
- 接口文檔在線自動生成,文檔隨接口變動實時更新,節省維護成本
- 支持在線接口測試,不依賴第三方工具
1.創建項目
(1)已idea爲例,創建項目所需要的dependencies
(2) 引入pom.xml依賴
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
(3) 創建Swagger2 配置類
package com.example.springbootswagger2.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author Kahen
* @create 2020-01-14 21:17
*/
@Configuration
@EnableSwagger2 //啓用Swagger2
public class Swagger2AutoConfiguration {
@Bean
public Docket swaggerSpringMvcPlugin(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) 掃描類上的Api註解也可以@RestController
// .apis(RequestHandlerSelectors.basePackage("com.example.springbootswagger2.controller"))
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().description("這是一個很NB的Api工具")
/*名片*/
.contact(new Contact("Kahen", "http://www.Kahen.com", "[email protected]"))
/*版本*/
.version("1.0")
/*所有者*/
.license("kahen")
//構造
.build();
}
}
Swagger2Configuration.java 配置類的內容不多,配置完成後也很少變化,簡單瞭解即可。
如上代碼所示,通過 @Configuration
註解,讓 Spring 加載該配置類。再通過 @EnableSwagger2
註解來啓用Swagger2。成員方法 createRestApi
函數創建 Docket
的Bean之後,apiInfo()
用來創建該 Api
的基本信息(這些基本信息會展現在文檔頁面中)。select()
函數返回一個 ApiSelectorBuilder
實例用來控制哪些接口暴露給 Swagger 來展現,本例採用指定掃描的ApiOperation
; 還有一種指定掃描類上的Api
註解也可以@RestController
,還有一種是指定掃描的包路徑來定義,Swagger 會掃描該包下所有 Controller 定義的 API,併產生文檔內容(除了被 @ApiIgnore
指定的請求)。
(4)本例需要模擬數據,創建一個ResultObj
類
package com.example.springbootswagger2.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author kahen
* @create 2020-01-14 19:09
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultObj {
private Integer status; //返回狀態
private Object msg; //返回消息
}
(5)創建User類
package com.example.springbootswagger2.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author kahen
* @create 2020-01-14 18:40
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer userId;
private String userName;
private String address;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
private Date birth;
}
(6) 創建 UserControlller
package com.example.springbootswagger2.controller;
import com.example.springbootswagger2.common.ResultObj;
import com.example.springbootswagger2.domain.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author kahen
* @create 2020-01-14 21:42
*/
@RestController
@RequestMapping("user")
@Api(value = "A", consumes = "用戶管理", produces = "B")
public class UserController {
/**
* 全查詢
*/
@ApiOperation(value = "用戶查詢", consumes = "查詢所有用戶")
@GetMapping("queryAllUser")
public List<User> queryAllUser() {
List<User> list = new ArrayList<>();
for (int i = 0; i <= 5; i++) {
list.add(new User(1, "小明" + i, "地球" + i, new Date()));
}
return list;
}
}
首先用全查詢測試
(7)啓動項目
查找Swagger的主頁,在包的Resources的html文件名就對了
訪問http://localhost:8080/swagger-ui.html
對應自己的Usercontroller,按try it out 進去調試,其餘自行試探
(8)調試時驗證
這裏我介紹幾個註解:
1、@RequestParam :加了@RequestParam後解決調試時驗證問題
2、@RestquestBody :要求驗證前端所有數非空同時要求必須提交json格式數據
3、@ApiImplicitParam:用在@ApiImplicitParams註解中,指定一個請求參數的各個方面
name:參數名
value:參數的漢字說明、解釋 required:參數是否必須傳
paramType:參數放在哪個地方
· header --> 請求參數的獲取:@RequestHeader
· query --> 請求參數的獲取:@RequestParam
· path(用於restful接口)--> 請求參數的獲取:@PathVariable
· body(不常用) · form(不常用)
dataType:參數類型,默認String,其它值dataType="Integer"
defaultValue:參數的默認值
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ofUERNXV-1579424108788)(https://github.com/Kahen/springboot-swagger2/raw/master/image/image-20200117124851887.png)]
展示其中一個,下面給出完整代碼
package com.example.springbootswagger2.controller;
import com.example.springbootswagger2.common.ResultObj;
import com.example.springbootswagger2.domain.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author kahen
* @create 2020-01-14 21:42
*/
@RestController
@RequestMapping("user")
@Api(value = "A", consumes = "用戶管理", produces = "B")
public class UserController {
/**
* 全查詢
*/
@ApiOperation(value = "用戶查詢", consumes = "查詢所有用戶")
@GetMapping("queryAllUser")
public List<User> queryAllUser() {
List<User> list = new ArrayList<>();
for (int i = 0; i <= 5; i++) {
list.add(new User(1, "小明" + i, "地球" + i, new Date()));
}
return list;
}
/**
* 根據id查詢用戶
*/
@ApiOperation(value = "根據id查詢用戶",consumes = "根據id查詢用戶")
@GetMapping("queryUserById")
public User queryUserByid(@RequestParam("UserId") Integer id) {//加了@RequestParam後解決調試時驗證問題
return new User(id, "小明", "廣東", new Date());
}
/**
*添加一個用戶
*/
@PostMapping("addUser")
@ApiOperation(value = "添加用戶")
@ApiImplicitParams(
value = {
@ApiImplicitParam(name="userId",value = "用戶標識",required = true,paramType = "Integer",dataType = "Integer")
}
)
// public ResultObj addUser(@RestquestBody User user){//要求驗證前端所有數非空同時要求必須提交json格式數據
public ResultObj addUser(User user){
System.out.println(user);
return new ResultObj(200,"添加成功");
}
/**
*修改一個用戶
*/
@PostMapping("updateUser")
@ApiOperation(value = "修改用戶")
@ApiImplicitParams(
value = {
@ApiImplicitParam(name="userId",value = "用戶標識",required = true,paramType = "Integer",dataType = "Integer")
}
)
// public ResultObj addUser(@RestquestBody User user){//要求驗證前端所有數非空同時要求必須提交json格式數據
public ResultObj updateUser(User user){
System.out.println(user);
return new ResultObj(200,"修改成功");
}
/**
* 根據id刪除用戶
*/
@DeleteMapping("deleteUser")
@ApiOperation(value = "刪除用戶")
public ResultObj deleteUser(@RequestParam("userId") Integer id){
System.out.println(id);
return new ResultObj(200,"刪除成功");
}
}
(9)更換皮膚
使用方法,把原來的swagger-ui 註釋了換上bootstrap-ui,啓動項目
<!-- <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
按照原來的方法尋找主頁
訪問http://localhost:8080/doc.html,得到主頁
由於本人實力有限,許多東西不夠完美,歡迎大家溝通交流