springboot整合swagger2(升級版)
簡述
為了項目的方便,整合一個接口文檔,swagger2的升級版knife4j,頁面跟簡單方便,功能也增強了不少,廢話不多說。
knife4j簡介
Swagger是一個API接口管理工具,支持在線測試接口數據,根據配置自動生成API文檔,結合spring mvc而提供界面化方法文檔的一個開源框架。
knife4j特點
文檔說明:根據Swagger的規范說明,詳細列出接口文檔的說明,包括接口地址、類型、請求示例、請求參數、響應示例、響應參數、響應碼等信息,使用swagger-bootstrap-ui能根據該文檔說明,對該接口的使用情況一目了然。
在線調試:提供在線接口聯調的強大功能,自動解析當前接口參數,同時包含表單驗證,調用參數可返回接口響應內容、headers、Curl請求命令實例、響應時間、響應狀態碼等信息,幫助開發者在線調試,而不必通過其他測試工具測試接口是否正確,簡介、強大。
knife4j整合到項目
Maven依賴
- springboot項目導入
<!--swagger2 增強版接口文檔-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
SwaggerConfig配置類
- 小編在配置類中添加了兩個模塊(即為兩個分組)
@Configuration//配置類注解
@EnableSwagger2
@EnableKnife4j //第三方swagger增強API注解
public class SwaggerConfig {
public static final String BASE_PACKAGE = "com.vx.music";//需要掃描的包
@Value("${swagger.enableSwagger}")
private Boolean enableSwagger ;
@Bean
public Docket createRestApi() {
//添加head參數start
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> operationParameters = new ArrayList<Parameter>();
tokenPar.name("Authorization").description("JWT").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
operationParameters.add(tokenPar.build());
//添加head參數end
return new Docket(DocumentationType.SWAGGER_2)
//將Timestamp類型全部轉為Long類型
.directModelSubstitute(Timestamp.class, Long.class)
//分分組名稱
.groupName("首頁模塊")
//將Date類型全部轉為Long類型
.directModelSubstitute(Date.class, Long.class)
.globalOperationParameters(operationParameters)
.apiInfo(apiInfo())
// 生產環境的時候關閉 swagger 比較安全
.enable(enableSwagger)
.select()
// 掃描接口的包路徑,不要忘記改成自己的
.apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE+".controller"))//拼接該模塊最后一級目錄
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket createRestApi2() {
//添加head參數start
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> operationParameters = new ArrayList<Parameter>();
tokenPar.name("Authorization").description("JWT").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
operationParameters.add(tokenPar.build());
//添加head參數end
return new Docket(DocumentationType.SWAGGER_2)
//將Timestamp類型全部轉為Long類型
.directModelSubstitute(Timestamp.class, Long.class)
//分分組名稱
.groupName("用戶模塊")
//將Date類型全部轉為Long類型
.directModelSubstitute(Date.class, Long.class)
.globalOperationParameters(operationParameters)
.apiInfo(apiInfo2())
// 生產環境的時候關閉 swagger 比較安全
.enable(enableSwagger)
.select()
// 掃描接口的包路徑,不要忘記改成自己的
.apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE+".LoginController"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("小程序接口文檔")
.description("首頁模塊API")
.termsOfServiceUrl("http://swagger.io/")
.contact(new Contact("ZHANGYU", "8.131.58.227:80/MusicVX/index.html", "2470838639@qq.com"))
.version("1.0")
.build();
}
private ApiInfo apiInfo2() {
return new ApiInfoBuilder()
.title("小程序接口文檔")//
.description("用戶模塊API")
.termsOfServiceUrl("http://8.131.58.227:80/MusicVX/index.html")
.contact(new Contact("ZHANGYU", "8.131.58.227:80/MusicVX/index.html", "2470838639@qq.com"))
.version("1.0")
.build();
}
注解說明
@EnableSwagger2
該注解是Springfox-swagger框架提供的使用Swagger注解,該注解必須加
@EnableKnife4j
該注解是knife4j提供的增強注解,Ui提供了例如動態參數、參數過濾、接口排序等增強功能,如果你想使用這些增強功能就必須加該注解,否則可以不用加
配置項目攔截器
/**
*攔截器
*/
@SpringBootApplication
@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Springboot項目配置文件
- application.properties配置文件,配置knife4j相關內容
#Swagger開關
swagger.enableSwagger=true
#配置swagger配置
knife4j.basic.username=admin
knife4j.basic.password=123
#開啟認證
knife4j.basic.enable=true
#默認是false ,屏蔽所有Swagger的相關資源 生產環境關閉
knife4j.production=false
修改啟動類
- 由於小編是一個多模塊的父子項目,所有需要修改啟動類,使web項目打war包
@SpringBootApplication
@MapperScan(value = "com.vx.music.dao")//掃描mapper接口
@ServletComponentScan//springboot打war注解
public class AppStartup extends SpringBootServletInitializer {//繼承SpringBootServletInitializer
@Override//重寫configure方法
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppStartup.class);
}
public static void main(String[] args) {
SpringApplication.run(AppStartup.class, args);
System.out.println("Application is Started !!! ");
logger.info("Application is Started !!! ");
}
}
使用注解生成接口文檔
實體類
@Data
@Builder
@ToString
@ApiModel(value = "MusicAdmin",description ="用戶實體類" )
public class MusicAdmin implements Serializable {
private Integer id;
@ApiModelProperty(value = "微信用戶唯一標識")
private String openid;
private String qq;
private String email;
private String majorid;
private String majorname;
}
接口類
- 接口上有比較多的注解,下面會在詳細講解,這里先把環境項目搭建,跑起來。
/**
* 測試
*/
@RestController
@RequestMapping("/test")
@Api(value="Hello Controller",tags={"測試接口類"})
public class HelloController {
@Autowired
private MusicAdminService musicAdminService;
@ApiOperation(value = "測試用戶列表", notes = "測試查詢單表",response =List.class )
@PostMapping("/selectAll")
public List<MusicAdmin> indexApp() {
List<MusicAdmin> musicAdminlist = musicAdminService.getAll();//可以換成自己的,或者輸出一句話
return musicAdminlist;
}
}
至此,我們是簡單整合好了,springboot+knife4j接口文檔,登錄測試,
訪問:
http://localhost:host/doc.html
knife4j相關注解詳解
Controller層添加注解
-
@Api:用於類;表示標識這個類是swagger的資源
屬性名稱 數據類型 默認值 說明 value String "" 字段說明 tags String[] "" 標簽說明 description String "" 詳情描述 basePath String "" 基本路徑可以不配置 position int "" 如果配置多個Api 想改變顯示的順序位置 produces String "" 提供者 (For example, "application/json, application/xml") consumes String "" 消費者(For example, "application/json, application/xml") protocols String "" 協議(Possible values: http, https, ws, wss.) authorizations Authorization[] "" 高級特性認證時配置 hidden boolean "" 配置為true 將在文檔中隱藏
使用示例
@Api(tags = "HELLO CONTROLLER 測試功能接口")//注解加載在controller類上
@RestController
public class HelloController {
}
-
@ApiResponses:在 Rest 接口上使用,用作返回值的描述
參數:屬性名稱 數據類型 默認值 說明 value ApiResponse[] "" 訪問對象 ApiResponse參數:
屬性名稱 數據類型 默認值 說明 code String "" 響應的HTTP狀態碼 message String "" 響應的信息內容 response Class<?> "" 用於描述消息有效負載的可選響應類,對應於響應消息對象的 schema 字段 reference String "" 指定對響應類型的引用,指定的應用可以使本地引用,也可以是遠程引用,將按原樣使用,並將覆蓋任何指定的response()類 responseHeaders ResponseHeader[] "" 聲明包裝響應的容器,有效值為List或Set,任何其他值都將被覆蓋 responseContainer String "" 聲明響應的容器,有效值為List,Set,Map,任何其他值都將被忽略 examples Example "" 例子
使用實例:
@ApiResponses(value = {
@ApiResponse(code = 200, message = "接口返回成功狀態"),
@ApiResponse(code = 500, message = "接口返回未知錯誤,請聯系開發人員調試")
})
@PostMapping("hello")
public Results<UserVO> hello(@RequestBody UserVO userVO){
Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
return results;
}
@ApiOperation:用在方法上,說明方法的作用,每一個url資源的定義
參數
屬性名稱 | 數據類型 | 默認值 | 說明 |
---|---|---|---|
value | String | "" | url的路徑值 |
notes | String | "" | 文本說明 |
tags | String[] | "" | 如果設置這個值、value的值會被覆蓋 |
response | Class<?> | "" | 返回的對象 |
responseContainer | String | "" | 聲明響應的容器,有效值為List,Set,Map,任何其他值都將被忽略 |
responseReference | String | "" | 聲明包裝響應的容器,有效值為List或Set,任何其他值都將被覆蓋 |
httpMethod | String | "" | "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH" |
position | int | "" | 如果配置多個Api 想改變顯示的順序位置 |
nickname | String | "" | 昵稱 |
produces | String | "" | 提供者 (For example, "application/json, application/xml") |
consumes | String | "" | 消費者(For example, "application/json, application/xml") |
protocols | String | "" | 協議(Possible values: http, https, ws, wss.) |
authorizations | Authorization[] | "" | 高級特性認證時配置 |
hidden | boolean | "" | 隱藏 |
responseHeaders | ResponseHeader[] | "" | 聲明包裝響應的容器,有效值為List或Set,任何其他值都將被覆蓋 |
code | String | "" | http的狀態碼 默認 200 |
extensions | Extension[] | "" | 擴展屬性 |
ignoreJsonView | boolean | "" | 是否忽略顯示 |
使用實例:
@ApiOperation(value = "Hello 測試接口", notes = "訪問此接口,返回hello語句,測試接口")
@PostMapping("hello")
public Results<UserVO> hello(@RequestBody UserVO userVO){
Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
return results;
}
@PathVariable:是獲取get方式,url后面參數,進行參數綁定(單個參數或兩個以內參數使用)
參數
屬性名稱 | 數據類型 | 默認值 | 說明 |
---|---|---|---|
value | String | "" | url的路徑值 |
name | String | "" | 重寫屬性名字 |
required | String | "" | 是否必填 |
使用實例:
@ApiResponses(value = {
@ApiResponse(code = 200, message = "接口返回成功狀態"),
@ApiResponse(code = 500, message = "接口返回未知錯誤,請聯系開發人員調試")
})
@ApiOperation(value = "獲取用戶信息", notes = "訪問此接口,返回用戶信息")
@PostMapping("/getUser/{id}")
public String getUser(@PathVariable String id) throws InterruptedException {
// 業務...
return "";
}
@RequestBody :在當前對象獲取整個http請求的body里面的所有數據(兩個以上參數封裝成對象使用)
參數
屬性名稱 | 數據類型 | 默認值 | 說明 |
---|---|---|---|
required | String | "" | 是否必填 |
使用實例:
@ApiResponses(value = {
@ApiResponse(code = 200, message = "接口返回成功狀態"),
@ApiResponse(code = 500, message = "接口返回未知錯誤,請聯系開發人員調試")
})
@ApiOperation(value = "Hello 測試接口", notes = "訪問此接口,返回hello語句,測試接口")
@PostMapping("hello")
public Results<UserVO> hello(@RequestBody UserVO userVO){
Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
return results;
}
相關問題
處理接口接收JSON數據的問題
- 當我們用老版本的swagger生成接口文檔時,它是不支持接口json數據的,只能傳java實體bean
- 在升級版中我們使用
@ApiOperationSupport
注解和@DynamicParameter
即可自動處理json數據
//首頁排行榜
@ApiOperation(value = "首頁排行榜 songList", notes = "首頁排行榜")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "接口返回成功狀態"),
@ApiResponse(code = 500, message = "接口返回未知錯誤,請聯系開發人員調試")
})
@ApiOperationSupport(params = @DynamicParameters(name = "obj",properties = {
@DynamicParameter(name = "pageNum",value = "當前頁數",example = "1",required = true,dataTypeClass = Integer.class),
@DynamicParameter(name = "pageSize",value = "每頁條數",example = "10",required = true,dataTypeClass = Integer.class),
@DynamicParameter(name = "Leaderboard_flag",value = "加載標識",example = "0",required = true,dataTypeClass = Integer.class)
}))
@PostMapping("/songList")
public ApiReturn selectSongList(@RequestBody JSONObject obj){
logger.info("查詢首頁排行榜歌曲分頁列表,obj={}",obj);
ApiReturn apiReturn = new ApiReturn();
PageVO page = new PageVO();
if ( obj != null && obj.getInteger(Constants.PAGE_NUM)!=null && obj.getInteger(Constants.PAGE_SIZE)!=null) {
page.setPageNum(obj.getInteger(Constants.PAGE_NUM));
page.setPageSize(obj.getInteger(Constants.PAGE_SIZE));
obj.remove(Constants.PAGE_NUM);
obj.remove(Constants.PAGE_SIZE);
}
HashMap<String,Object> songMap =songListService.selectSongList(page,obj);
apiReturn.setData(songMap);
apiReturn.isSuccess();
return apiReturn;
}