技術(shù)分享 | Spring Boot 集成 Swagger
Swagger UI 允許任何人(無論您是開發(fā)團隊還是最終用戶)都可以可視化 API 資源并與之交互,而無需任何實現(xiàn)邏輯。它是根據(jù)您的 OpenAPI(以前稱為 Swagger)規(guī)范自動生成的,具有可視化文檔,可簡化后端實現(xiàn)和客戶端使用。
為什么使用Swagger
跨語言性,支持 40 多種語言,Swagger 已經(jīng)慢慢演變成了 OpenAPI 規(guī)范;
Swagger UI 呈現(xiàn)出來的是一份可交互式的 API 文檔,我們可以直接在文檔頁面嘗試 API 的調(diào)用,省去了準(zhǔn)備復(fù)雜的調(diào)用參數(shù)的過程;
對于某些沒有前端界面 UI 的功能,可以用它來測試接口;
聯(lián)調(diào)方便,如果出問題,直接測試接口,實時檢查參數(shù)和返回值,就可以快速定位問題。
Swagger快速開始
這里選擇 2.9.2 版本。
<!-- swagger -->?
<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>
添加配置類
添加一個 Swagger 配置類,在工程下新建 config 包并添加一個 SwaggerConfig 配置類。
SwaggerConfig.java?
```java
import com.google.common.collect.Lists;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.schema.ModelRef;
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;
@Configuration?
@EnableSwagger2?
public class SwaggerConfig {?
? ?//作為Springfox框架的主要接口的構(gòu)建器,提供合理的默認(rèn)值和方便的配置方法。
? ?@Bean?
? ?public Docket docket() {
? ??
? ?ParameterBuilder builder = new ParameterBuilder();
? ? ? ?builder.parameterType("header").name("token")
? ? ? ? ? ? ? ?.description("token值")
? ?
? ? ? ? ? ?.required(true)
? ?
?? ? ? ? ? ?.modelRef(new ModelRef("string")); // 在swagger里顯示header
? ? ? ?return new Docket(DocumentationType.SWAGGER_2)
? ? ? ? ? ? ? ?.groupName("aitest_interface")
? ? ? ? ?
? ? ?.apiInfo(apiInfo())
? ? ? ? ? ? ? ?.globalOperationParameters(Lists.newArrayList(builder.build()))
? ? ? ? ? ? ? ?.select().paths(PathSelectors.any()).build();
??
?}
?
??private ApiInfo apiInfo() {
? ?
?? ?return new ApiInfoBuilder()
? ??
? ? ? ? ? ?.title("aitest-mini系統(tǒng)")
?
?? ? ? ? ? ? ?.description("aitest-mini接口文檔")
? ? ? ? ? ? ? ?.contact(new Contact("tlibn", "", "103@qq.com"))
? ? ? ? ? ? ? ?.version("1.0")
? ? ? ?
?? ? ? ?.build();
??
?}
?}
?添加控制器
添加一個控制器,在工程下新建 controller包并添加一個Controller控制器,如果已經(jīng)存在Controller控制器,則直接啟動服務(wù)也可以,如上章我們編寫了HogwartsTestUserController類,此時直接啟動服務(wù)即可。
打開 swagger 接口文檔界面
啟動 Spring Boot 服務(wù),打開瀏覽器,訪問:http://127.0.0.1:8081/swagger-ui.html,進入swagger接口文檔界面。 6
測試
展開 hogwarts-test-user-controller 的任意接口,輸入?yún)?shù)并點擊執(zhí)行,就可以看到接口測試結(jié)果了。?

Swagger 常用注解
swagger 通過注解表明該接口會生成文檔,包括接口名、請求方法、參數(shù)、返回信息的等等。
Api:修飾整個類,描述 Controller 的作用
Api(tags = “霍格沃茲測試學(xué)院-用戶管理模塊”, hidden = true)
ApiOperation:描述一個類的一個方法,或者說一個接口
ApiOperation(“查詢用戶列表”)
ApiParam:單個參數(shù)描述
ApiModel:用對象來接收參數(shù)
ApiModel(value = “用戶登錄類”, description = “請求類”)
ApiProperty:用對象接收參數(shù)時,描述對象的一個字段
ApiModelProperty(value=“用戶id”, example=“1”,required=true)
ApiResponse:HTTP 響應(yīng)其中 1 個描述
ApiResponses:HTTP 響應(yīng)整體描述
ApiIgnore:使用該注解忽略這個 API
ApiError :發(fā)生錯誤返回的信息
ApiImplicitParam:一個請求參數(shù)
ApiImplicitParams:多個請求參數(shù)
更多參見 https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X#quick-annotation-overview
添加 Swagger 常用注解后的效果


添加 Swagger 常用注解后的示例代碼
HogwartsTestUserController.java
@Api(tags = “霍格沃茲測試學(xué)院-用戶管理模塊”, hidden = true)
@RestController
@RequestMapping("/api/user")
public class HogwartsTestUserController {
/**?
* 查詢用戶列表,返回一個JSON數(shù)組
?* */?
@ApiOperation("查詢用戶列表")?
@GetMapping("/users")
@ResponseStatus(HttpStatus.OK)?
public Object getUsers(){
?
?List<UserDto> list = getData();
?
?return list;
}
/**?
* 查詢用戶信息,返回一個新建的JSON對象?
* */?
@ApiOperation("查詢用戶信息")?
@GetMapping("/users/{id}")
@ResponseStatus(HttpStatus.OK)?
public Object getUser(@PathVariable("id") Long id){
? ?if(Objects.isNull(id)){?
? ? ? ?return null;
?
?}
??
?List<UserDto> list= getData();
?
?UserDto userDto = getUserDto(id, list);
?
?return userDto;?
}
/**?
* 新增用戶?
* */
@ApiOperation("新增用戶")?
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public Object addUser(@RequestBody UserDto user){?
? ?List<UserDto> list= getData();
?
?list.add(user);//模擬向列表中增加數(shù)據(jù)?
? ?return user;
}?
/**
?* 編輯用戶
?* */
@ApiOperation("編輯用戶")
@PutMapping("/users/{id}")?
@ResponseStatus(HttpStatus.CREATED)?
public Object editUser(@PathVariable("id") Long id,@RequestBody UserDto user){
??
?List<UserDto> list = getData();?
? ?for (UserDto userDto:list) {?
? ? ? ?if(id.equals(userDto.getId())){
??
? ? ? ? ?userDto = user;
?
? ? ? ? ?break;
?
? ? ?}
??
?}
?
?return user;?
}?
/**?
* 刪除用戶?
* */
?@ApiOperation("刪除用戶")
@DeleteMapping("/users/{id}")?
@ResponseStatus(HttpStatus.NO_CONTENT)?
public Object deleteUser(@PathVariable("id") Long id){?
?? ?List<UserDto> list = getData();
?? ?UserDto userDto = getUserDto(id, list);?
? ?return ?userDto;?
}?
/**
?* 模擬數(shù)據(jù)?
* */
private List<UserDto> getData(){?
? ?List<UserDto> list=new ArrayList<>();?
? ?UserDto userDto = new UserDto();?
? ?userDto.setId(1L);
? ?
userDto.setName("admin");
?
??userDto.setPwd("admin");
?
??list.add(userDto);
??
?userDto = new UserDto();?
?? ?userDto.setId(2L);
?
??userDto.setName("HogwartsTest1");
?
??userDto.setPwd("HogwartsTest1");?
?? ?list.add(userDto);
?
??userDto = new UserDto();
??
?userDto.setId(3L);?
?? ?userDto.setName("HogwartsTest2");
??
?userDto.setPwd("HogwartsTest2");
??
?list.add(userDto);
??
?userDto = new UserDto();
??
?userDto.setId(4L);?
?? ?userDto.setName("HogwartsTest3");
?
??userDto.setPwd("HogwartsTest3");?
??list.add(userDto);
??
?return ?list;
}?
?/**?
?* ?模擬根據(jù)id查詢列表中的數(shù)據(jù)
?* @param id
?* @param list
?* @return?
*/
?private UserDto getUserDto( Long id, List<UserDto> list) {
??
?UserDto UserDto = null;?
?? ?for (UserDto user : list) {
??
? ? ?if (id.equals(user.getId())) {
??
? ? ? ? ?UserDto = user;
? ??
? ? ? ?break;
? ? ??
?}
??
?}
?
?return UserDto;
}
}
UserDto.java
@ApiModel(value = “用戶登錄類”, description = “請求類”)
public class UserDto {
@ApiModelProperty(value="用戶id", example="1",required=true)?
private Long id;
?@ApiModelProperty(value="用戶名稱", example="hogwarts1",required=true)
private String name;?
@ApiModelProperty(value="用戶密碼", example="hogwarts2",required=true)?
private String pwd;?
public Long getId() {?
? ? return id;?
?}
public void setId(Long id) {
?
? this.id = id;?
}
public String getName() {
?
? return name;?
?}?
?public void setName(String name) {?
? ? this.name = name;?
?}?
public String getPwd() {?
? ? return pwd;
}
?public void setPwd(String pwd) {?
? ? this.pwd = pwd;
}
}