亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁 > IT技術(shù) > Windows編程 > 正文

              API中文文檔:Swagger詳解
              2021-10-27 14:31:33

              目前來說,在 Java 領(lǐng)域使用?Springboot?構(gòu)建微服務(wù)是比較流行的,在構(gòu)建微服務(wù)時,我們大多數(shù)會選擇暴漏一個 REST API 以供調(diào)用。又或者公司采用前后端分離的開發(fā)模式,讓前端和后端的工作由完全不同的工程師進(jìn)行開發(fā)完成。不管是微服務(wù)還是這種前后端分離開發(fā),維持一份完整的及時更新的 REST API 文檔,會極大的提高我們的工作效率。而傳統(tǒng)的文檔更新方式(如手動編寫),很難保證文檔的及時性,經(jīng)常會年久失修,失去應(yīng)有的意義。因此選擇一種新的 API 文檔維護(hù)方式很有必要,這也是這篇文章要介紹的內(nèi)容。

              1. OpenAPI 規(guī)范介紹

              OpenAPI Specification 簡稱 OAS,中文也稱 OpenAPI 描述規(guī)范,使用 OpenAPI 文件可以描述整個 API,它制定了一套的適合通用的與語言無關(guān)的 REST API 描述規(guī)范,如 API 路徑規(guī)范、請求方法規(guī)范、請求參數(shù)規(guī)范、返回格式規(guī)范等各種相關(guān)信息,使人類和計算機(jī)都可以不需要訪問源代碼就可以理解和使用服務(wù)的功能。

              下面是 OpenAPI 規(guī)范中建議的 API 設(shè)計規(guī)范,基本路徑設(shè)計規(guī)范。

              https://api.example.com/v1/users?role=admin&status=active________________________/____/ ______________________/ server URL endpoint query parameters path

              對于傳參的設(shè)計也有規(guī)范,可以像下面這樣:

              路徑參數(shù) , 例如 /users/{id}

              查詢參數(shù) , 例如 /users?role=未讀代碼

              header 參數(shù) , 例如 X-MyHeader: Value

              cookie 參數(shù) , 例如 Cookie: debug=0; csrftoken=BUSe35dohU3O1MZvDCU

              OpenAPI 規(guī)范的東西遠(yuǎn)遠(yuǎn)不止這些,目前 OpenAPI 規(guī)范最新版本是 3.0.2,如果你想了解更多的 OpenAPI 規(guī)范,可以訪問下面的鏈接。

              OpenAPI Specification (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md)

              2. Swagger 介紹

              很多人都以為 Swagger 只是一個接口文檔生成框架,其實并不是。 Swagger 是一個圍繞著 OpenAPI Specification (OAS,中文也稱 OpenAPI規(guī)范)構(gòu)建的一組開源工具。可以幫助你從 API 的設(shè)計到 API 文檔的輸出再到 API 的測試,直至最后的 API 部署等整個 API 的開發(fā)周期提供相應(yīng)的解決方案,是一個龐大的項目。 Swagger 不僅免費,而且開源,不管你是企業(yè)用戶還是個人玩家,都可以使用 Swagger 提供的方案構(gòu)建令人驚艷的 REST API 。

              Swagger 有幾個主要的產(chǎn)品。

              Swagger Editor – 一個基于瀏覽器的 Open API 規(guī)范編輯器。

              Swagger UI – 一個將 OpenAPI 規(guī)范呈現(xiàn)為可交互在線文檔的工具。

              Swagger Codegen – 一個根據(jù) OpenAPI 生成調(diào)用代碼的工具。

              如果你想了解更多信息,可以訪問 Swagger 官方網(wǎng)站 https://swagger.io 。

              3. Springfox 介紹

              源于 Java 中 Spring 框架的流行,讓一個叫做 Marrty Pitt 的老外有了為 SpringMVC 添加接口描述的想法,因此他創(chuàng)建了一個遵守 OpenAPI 規(guī)范(OAS)的項目,取名為 swagger-springmvc,這個項目可以讓 Spring 項目自動生成 JSON 格式的 OpenAPI 文檔。這個框架也仿照了 Spring 項目的開發(fā)習(xí)慣,使用注解來進(jìn)行信息配置。

              后來這個項目發(fā)展成為 Springfox ,再后來擴(kuò)展出 springfox-swagger2 ,為了讓 JSON 格式的 API 文檔更好的呈現(xiàn),又出現(xiàn)了 springfox-swagger-ui 用來展示和測試生成的 OpenAPI 。這里的 springfox-swagger-ui 其實就是上面介紹的 Swagger-ui,只是它被通過 webjar 的方式打包到 jar 包內(nèi),并通過 maven 的方式引入進(jìn)來。

              上面提到了 Springfox-swagger2 也是通過注解進(jìn)行信息配置的,那么是怎么使用的呢?下面列舉常用的一些注解,這些注解在下面的 Springboot 整合 Swagger 中會用到。

              注解示例描述@ApiModel@ApiModel(value = “用戶對象”)描述一個實體對象@ApiModelProperty@ApiModelProperty(value = “用戶ID”, required = true, example = “1000”)描述屬性信息,執(zhí)行描述,是否必須,給出示例@Api@Api(value = “用戶操作 API(v1)”, tags = “用戶操作接口”)用在接口類上,為接口類添加描述@ApiOperation@ApiOperation(value = “新增用戶”)描述類的一個方法或者說一個接口@ApiParam@ApiParam(value = “用戶名”, required = true)描述單個參數(shù)

              更多的 Springfox 介紹,可以訪問 Springfox 官方網(wǎng)站。

              Springfox Reference Documentation (http://springfox.github.io)

              4. Springboot 整合 Swagger

              就目前來說 ,Springboot 框架是非常流行的微服務(wù)框架,在微服務(wù)框架下,很多時候我們都是直接提供 REST API 的。REST API 如果沒有文檔的話,使用者就很頭疼了。不過不用擔(dān)心,上面說了有一位叫 Marrty Pitt 的老外已經(jīng)創(chuàng)建了一個發(fā)展成為 Springfox 的項目,可以方便的提供 JSON 格式的 OpenAPI 規(guī)范和文檔支持。且擴(kuò)展出了 springfox-swagger-ui 用于頁面的展示。

              需要注意的是,這里使用的所謂的 Swagger 其實和真正的 Swagger 并不是一個東西,這里使用的是 Springfox 提供的 Swagger 實現(xiàn)。它們都是基于 OpenAPI 規(guī)范進(jìn)行 API 構(gòu)建。所以也都可以 Swagger-ui 進(jìn)行 API 的頁面呈現(xiàn)。

              (1)創(chuàng)建項目

              如何創(chuàng)建一個 Springboot 項目這里不提,你可以直接從 Springboot 官方 下載一個標(biāo)準(zhǔn)項目,也可以使用 idea 快速創(chuàng)建一個 Springboot 項目,也可以順便拷貝一個 Springboot 項目過來測試,總之,方式多種多樣,任你選擇。

              下面演示如何在 Springboot 項目中使用 swagger2。

              (2)引入依賴

              這里主要是引入了 springfox-swagger2,可以通過注解生成 JSON 格式的 OpenAPI 接口文檔,然后由于 Springfox 需要依賴 jackson,所以引入之。springfox-swagger-ui 可以把生成的 OpenAPI 接口文檔顯示為頁面。Lombok 的引入可以通過注解為實體類生成 get/set 方法。

              org.springframework.boot spring-boot-starter-web  spring-boot-starter-json org.springframework.bootio.springfox springfox-swagger2 2.9.2io.springfox springfox-swagger-ui 2.9.2com.fasterxml.jackson.core jackson-databind 2.5.4org.projectlombok lombok true

              (3)配置 Springfox-swagger

              Springfox-swagger 的配置通過一個 Docket 來包裝,Docket 里的 apiInfo 方法可以傳入關(guān)于接口總體的描述信息。而 apis 方法可以指定要掃描的包的具體路徑。在類上添加 @Configuration 聲明這是一個配置類,最后使用 @EnableSwagger2 開啟 Springfox-swagger2。

              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;/** * 

              * Springfox-swagger2 配置 * * @Author niujinpeng * @Date 2019/11/19 23:17 */@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("net.codingme.boot.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("未讀代碼 API") .description("公眾號:未讀代碼(weidudaima) springboot-swagger2 在線借口文檔") .termsOfServiceUrl("https://www.codingme.net") .contact("達(dá)西呀") .version("1.0") .build(); }}

              (4)代碼編寫

              文章不會把所有代碼一一列出來,這沒有太大意義,所以只貼出主要代碼,完整代碼會上傳到 Github,并在文章底部附上 Github 鏈接。

              參數(shù)實體類 User.java ,使用 @ApiModel 和 @ApiModelProperty 描述參數(shù)對象,使用 @NotNull 進(jìn)行數(shù)據(jù)校驗,使用 @Data 為參數(shù)實體類自動生成 get/set 方法。

              import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.format.annotation.DateTimeFormat;import javax.validation.constraints.NotNull;import java.util.Date;/** * 

              * 用戶實體類 * * @Author niujinpeng * @Date 2018/12/19 17:13 */@Data@NoArgsConstructor@AllArgsConstructor@ApiModel(value = "用戶對象")public class User { /** * 用戶ID * * @Id 主鍵 * @GeneratedValue 自增主鍵 */ @NotNull(message = "用戶 ID 不能為空") @ApiModelProperty(value = "用戶ID", required = true, example = "1000") private Integer id; /** * 用戶名 */ @NotNull(message = "用戶名不能為空") @ApiModelProperty(value = "用戶名", required = true) private String username; /** * 密碼 */ @NotNull(message = "密碼不能為空") @ApiModelProperty(value = "用戶密碼", required = true) private String password; /** * 年齡 */ @ApiModelProperty(value = "用戶年齡", example = "18") private Integer age; /** * 生日 */ @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") @ApiModelProperty(value = "用戶生日") private Date birthday; /** * 技能 */ @ApiModelProperty(value = "用戶技能") private String skills;}

              編寫 Controller 層,使用 @Api 描述接口類,使用 @ApiOperation 描述接口,使用 @ApiParam描述接口參數(shù)。代碼中在查詢用戶信息的兩個接口上都添加了 tags = "用戶查詢" 標(biāo)記,這樣這兩個方法在生成 Swagger 接口文檔時候會分到一個共同的標(biāo)簽組里。

              import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.annotations.ApiParam;import lombok.extern.slf4j.Slf4j;import net.codingme.boot.domain.Response;import net.codingme.boot.domain.User;import net.codingme.boot.enums.ResponseEnum;import net.codingme.boot.utils.ResponseUtill;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.*;import javax.validation.Valid;import javax.validation.constraints.NotNull;import java.util.ArrayList;import java.util.List;/** * 

              * 用戶操作 * * @Author niujinpeng * @Date 2019/11/19 23:17 */@Slf4j@RestController(value = "/v1")@Api(value = "用戶操作 API(v1)", tags = "用戶操作接口")public class UserController { @ApiOperation(value = "新增用戶") @PostMapping(value = "/user") public Response create(@Valid User user, BindingResult bindingResult) throws Exception { if (bindingResult.hasErrors()) { String message = bindingResult.getFieldError().getDefaultMessage(); log.info(message); return ResponseUtill.error(ResponseEnum.ERROR.getCode(), message); } else { // 新增用戶信息 do something return ResponseUtill.success("用戶[" + user.getUsername() + "]信息已新增"); } } @ApiOperation(value = "刪除用戶") @DeleteMapping(value = "/user/{username}") public Response delete(@PathVariable("username") @ApiParam(value = "用戶名", required = true) String name) throws Exception { // 刪除用戶信息 do something return ResponseUtill.success("用戶[" + name + "]信息已刪除"); } @ApiOperation(value = "修改用戶") @PutMapping(value = "/user") public Response update(@Valid User user, BindingResult bindingResult) throws Exception { if (bindingResult.hasErrors()) { String message = bindingResult.getFieldError().getDefaultMessage(); log.info(message); return ResponseUtill.error(ResponseEnum.ERROR.getCode(), message); } else { String username = user.getUsername(); return ResponseUtill.success("用戶[" + username + "]信息已修改"); } } @ApiOperation(value = "獲取單個用戶信息", tags = "用戶查詢") @GetMapping(value = "/user/{username}") public Response get(@PathVariable("username") @NotNull(message = "用戶名稱不能為空") @ApiParam(value = "用戶名", required = true) String username) throws Exception { // 查詢用戶信息 do something User user = new User(); user.setId(10000); user.setUsername(username); user.setAge(99); user.setSkills("cnp"); return ResponseUtill.success(user); } @ApiOperation(value = "獲取用戶列表", tags = "用戶查詢") @GetMapping(value = "/user") public Response selectAll() throws Exception { // 查詢用戶信息列表 do something User user = new User(); user.setId(10000); user.setUsername("未讀代碼"); user.setAge(99); user.setSkills("cnp"); List userList = new ArrayList<>(); userList.add(user); return ResponseUtill.success(userList); }}

              最后,為了讓代碼變得更加符合規(guī)范和好用,使用一個統(tǒng)一的類進(jìn)行接口響應(yīng)。

              @Data@AllArgsConstructor@NoArgsConstructor@ApiModel(value = "響應(yīng)信息")public class Response { /** * 響應(yīng)碼 */ @ApiModelProperty(value = "響應(yīng)碼") private String code; /** * 響應(yīng)信息 */ @ApiModelProperty(value = "響應(yīng)信息") private String message; /** * 響應(yīng)數(shù)據(jù) */ @ApiModelProperty(value = "響應(yīng)數(shù)據(jù)") private Collection content;}

              (5)運行訪問

              直接啟動 Springboog 項目,可以看到控制臺輸出掃描到的各個接口的訪問路徑,其中就有 /2/api-docs 。

              這個也就是生成的 OpenAPI 規(guī)范的描述 JSON 訪問路徑,訪問可以看到。

              因為上面我們在引入依賴時,也引入了 springfox-swagger-ui 包,所以還可以訪問 API 的頁面文檔。訪問路徑是 /swagger-ui.html,訪問看到的效果可以看下圖。

              也可以看到用戶查詢的兩個方法會歸到了一起,原因就是這兩個方法的注解上使用相同的 tag 屬性。

              (6)調(diào)用測試

              springfox-swagger-ui 不僅是生成了API文檔,還提供了調(diào)用測試功能。下面是在頁面上測試獲取單個用戶信息的過程。

              點擊接口 [/user/{username}] 獲取單個用戶信息。

              點擊 **Try it out** 進(jìn)入測試傳參頁面。

              輸入?yún)?shù),點擊 Execute 藍(lán)色按鈕執(zhí)行調(diào)用。

              查看返回信息。

              5. 常見報錯

              如果你在程序運行中經(jīng)常發(fā)現(xiàn)像下面這樣的報錯。

              java.lang.NumberFormatException: For input string: ""at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_111]at java.lang.Long.parseLong(Long.java:601) ~[na:1.8.0_111]at java.lang.Long.valueOf(Long.java:803) ~[na:1.8.0_111]at io.swagger.models.parameters.AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412) ~[swagger-models-1.5.20.jar:1.5.20]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:536) [jackson-databind-2.5.4.jar:2.5.4]at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666) [jackson-databind-2.5.4.jar:2.5.4]at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) [jackson-databind-2.5.4.jar:2.5.4]at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:113) [jackson-databind-2.5.4.jar:2.5.4]

              那么你需要檢查使用了 @ApiModelProperty 注解且字段類型為數(shù)字類型的屬性上, @ApiModelProperty 注解是否設(shè)置了 example 值,如果沒有,那就需要設(shè)置一下,像下面這樣。

              @NotNull(message = "用戶 ID 不能為空")@ApiModelProperty(value = "用戶ID", required = true, example = "10


              本文摘自 :https://blog.51cto.com/u

              開通會員,享受整站包年服務(wù)立即開通 >