1、問題描述
隨着互聯網技術的發展,現在的網站架構基本都由原來的後端渲染,變成了:前端渲染、前後端分離的形態,而且前端技術和後端技術在各自的道路上越走越遠。 前端和後端的唯一聯繫,變成了API接口;API文檔變成了前後端開發人員聯繫的紐帶,變得越來越重要。沒有API文檔工具之前,大家都是手寫API文檔的(維護起來相當困難),在什麼地方書寫的都有,有在confluence
上寫的,有在對應的項目目錄下readme.md
上寫的,每個公司都有每個公司的玩法,無所謂好壞。但是能稱之爲“框架”的,估計也只有swagger
了。
首先對swagger做一個簡介吧:是一款讓你更好的書寫API文檔的框架; swagger是後臺開發的神器,也是前後端交流的渠道。你可以用swagger做什麼?首先,你以後基本可以告別單元測試了;其次,你不用再寫接口文檔了,也不需要寫完之後再去對文檔進行維護了;swagger可以完全模擬http請求,入參出參和實際情況差別幾乎爲零。
2、操作步驟
2.1 配置:導入兩個依賴包
implementation "io.springfox:springfox-swagger2:2.9.2"
implementation "io.springfox:springfox-swagger-ui:2.9.2"
2.2 添加 swagger 配置類
package com.example.demo.config;
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.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2 //添加swagger啓用註解
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")) // 注意修改此處的包名
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger2-集成系統")
.description("API接口文檔")
.version("1.1.0")
.build();
}
}
2.3 在類、方法、參數上添加註解
package com.example.demo.controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(description = "測試類")
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/get")
@ApiOperation(value = "測試Swagger", notes = "測試Swagger2", httpMethod = "GET", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "姓名", dataType = "String")
})
public String sayHello(String name) throws Exception {
return name + " hello Swagger!";
}
}
2.4 啓動服務:瀏覽器輸入http://ip:port/swagger-ui.html
http://localhost:8080/swagger-ui.html
出現下面的畫面就代表大功告成
2.5 如何解決線上接口不被暴露?
[1] 生產環境移除Swagger2
* 使用註解 @Profile({"dev", "test"}) 表示在“開發”或“測試”環境開啓,而在生產關閉
[2] 使用springboot security過濾
* 使用註解 @ConditionalOnProperty(name = "swagger2.enable", havingValue = "true")
* 然後在“開發”或“測試”配置中添加 swagger2.enable=true 即可開啓,生產環境不配置則默認關閉Swagger.
[3] 直接使用多環境配置,生產環境不啓用Swagger2 (推薦使用)
* application-xxx.yml文件
swagger2:
enable: false/true
* 調整 swagger 配置類
@Value("${swagger2.enable}")
private boolean swagger2Enable;
Docket(DocumentationType.SWAGGER_2).enable(swagger2Enable).build();
[4] 三種配置方式源碼,如下:
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2 //添加swagger啓用註解
//@Profile({"dev", "test"}) //方式一
//@ConditionalOnProperty(name = "swagger2.enable", havingValue = "true") //方式二
public class Swagger2 {
//讀取yml文件配置
@Value("${swagger2.enable}")
private boolean swagger2Enable;
/**
* .enable() 控制是否進行初始化
* .select() 初始化並返回一個API選擇構造器
* .paths(PathSelectors.any()) 設置路徑篩選器
* .apis(RequestHandlerSelectors.basePackage("com.xxx.xxx.xxx")) 添加路徑選擇條件
* .build(); 構建
*
* PathSelectors 類的方法:
* - Predicate<String> any():滿足條件的路徑,該斷言總爲true
* - Predicate<String> none():不滿足條件的路徑,該斷言總爲false
* - Predicate<String> regex(final String pathRegex):符合正則的路徑
*
* RequestHandlerSelectors 類的方法:
* - Predicate<RequestHandler> any():返回包含所有滿足條件的請求處理器的斷言,該斷言總爲true
* - Predicate<RequestHandler> none():返回不滿足條件的請求處理器的斷言,該斷言總爲false
* - Predicate<RequestHandler> basePackage(final String basePackage):返回一個斷言(Predicate),該斷言包含所有匹配basePackage下所有類的請求路徑的請求處理器
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(swagger2Enable) //方式三
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")) // 注意修改此處的包名
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger2-集成系統")
.description("API接口文檔")
.version("1.1.0")
.build();
}
}