一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

2022-03-03 00:48飄渺Jam Java教程

這篇文章主要為大家介紹了java集成開發(fā)SpringBoot如何生成接口文檔的示例實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助

大家好,我是飄渺。

SpringBoot老鳥系列的文章已經(jīng)寫了兩篇,每篇的閱讀反響都還不錯,果然大家還是對SpringBoot比較感興趣。那今天我們就帶來老鳥系列的第三篇:集成Swagger接口文檔以及Swagger的高級功能。 文章涉及到的代碼已經(jīng)上傳到了github,希望最終能應(yīng)用在你們實(shí)際項(xiàng)目上,當(dāng)然如果有其他需要我添加到內(nèi)容也可以直接留言告訴我,我會視情況給你們加上去的。

SpringBoot 如何統(tǒng)一后端返回格式?老鳥們都是這樣玩的!

SpringBoot 如何進(jìn)行參數(shù)校驗(yàn)? 老鳥們都是這樣玩的!

好了,閑話少敘,讓我們先來看看為什么要用Swagger?

 

為什么要用Swagger ?

作為一名程序員,我們最討厭兩件事:1. 別人不寫注釋。2. 自己寫注釋。

而作為一名接口開發(fā)者,我們同樣討厭兩件事:

1. 別人不寫接口文檔,文檔不及時更新。

2. 需要自己寫接口文檔,還需要及時更新。

相信無論是前端還是后端開發(fā),都或多或少地被接口文檔折磨過。前端經(jīng)常抱怨后端給的接口文檔與實(shí)際情況不一致。后端又覺得編寫及維護(hù)接口文檔會耗費(fèi)不少精力,經(jīng)常來不及更新。

而隨著Springboot、Springcloud等微服務(wù)的流行,每個項(xiàng)目都有成百上千個接口調(diào)用,這時候再要求人工編寫接口文檔并且保證文檔的實(shí)時更新幾乎是一件不可能完成的事,所以這時候我們迫切需要一個工具,一個能幫我們自動化生成接口文檔以及自動更新文檔的工具。它就是Swagger。

Swagger 提供了一個全新的維護(hù) API 文檔的方式,有4大優(yōu)點(diǎn):

自動生成文檔:只需要少量的注解,Swagger 就可以根據(jù)代碼自動生成 API 文檔,很好的保證了文檔的時效性。

跨語言性,支持 40 多種語言。

Swagger UI 呈現(xiàn)出來的是一份可交互式的 API 文檔,我們可以直接在文檔頁面嘗試 API 的調(diào)用,省去了準(zhǔn)備復(fù)雜的調(diào)用參數(shù)的過程。

還可以將文檔規(guī)范導(dǎo)入相關(guān)的工具(例如 SoapUI), 這些工具將會為我們自動地創(chuàng)建自動化測試。

現(xiàn)在我們知道了Swagger的作用,接下來將其集成到我們項(xiàng)目中。

 

Swagger集成

集成Swagger很簡單,只需要簡單三步。

第一步: 引入依賴包

<!--swagger-->
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger2</artifactId>
  <version>2.9.2</version>
</dependency>

<!--swagger-ui-->
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger-ui</artifactId>
  <version>2.9.2</version>
</dependency>

第二步:修改配置文件

application.properties 加入配置

# 用于控制是否開啟Swagger,生產(chǎn)環(huán)境記得關(guān)閉Swagger,將值設(shè)置為 false
springfox.swagger2.enabled = true

增加一個swagger配置類

@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
public class SwaggerConfig {

  private static final String VERSION = "1.0";

  @Value("${springfox.swagger2.enabled}")
  private Boolean swaggerEnabled;

  @Bean
  public Docket createRestApi(){
      return new Docket(DocumentationType.SWAGGER_2)
              .enable(swaggerEnabled)
              .groupName("SwaggerDemo")
              .apiInfo(apiInfo())
              .select()
              .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
              .paths(PathSelectors.any())
              .build();
  }

  /**
   * 添加摘要信息
   */
  private ApiInfo apiInfo() {
      return new ApiInfoBuilder()
              .title("接口文檔")
              .contact(new Contact("JAVA日知錄","http://javadaily.cn","[email protected]"))
              .description("Swagger接口文檔")
              .version(VERSION)
              .build();
  }

}

這里通過 .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))

表面給加上 @Api注解的類自動生成接口文檔。

第三步,配置API接口

@RestController
@Api(tags = "參數(shù)校驗(yàn)")
@Slf4j
@Validated
public class ValidController {

  @PostMapping("/valid/test1")
  @ApiOperation("RequestBody校驗(yàn)")
  public String test1(@Validated @RequestBody ValidVO validVO){
      log.info("validEntity is {}", validVO);
      return "test1 valid success";
  }

  @ApiOperation("Form校驗(yàn)")
  @PostMapping(value = "/valid/test2")
  public String test2(@Validated ValidVO validVO){
      log.info("validEntity is {}", validVO);
      return "test2 valid success";
  }

  @ApiOperation("單參數(shù)校驗(yàn)")
  @PostMapping(value = "/valid/test3")
  public String test3(@Email String email){
      log.info("email is {}", email);
      return "email valid success";
  }
}

通過 @Api注解標(biāo)注需要生成接口文檔,通過 @ApiOperation注解標(biāo)注接口名。

同時我們給 ValidVO也加上對應(yīng)的注解

@Data
@ApiModel(value = "參數(shù)校驗(yàn)類")
public class ValidVO {

  @ApiModelProperty("ID")
  private String id;

  @ApiModelProperty(value = "應(yīng)用ID",example = "cloud")
  private String appId;

  @NotEmpty(message = "級別不能為空")
  @ApiModelProperty(value = "級別")
  private String level;

  @ApiModelProperty(value = "年齡")
  private int age;

  ...

}

通過 @ApiModel標(biāo)注這是一個參數(shù)實(shí)體,通過 @ApiModelProperty標(biāo)注字段說明。

 

Unable to infer base url

簡單三步,我們項(xiàng)目就集成了Swagger接口文檔,趕緊啟動服務(wù),訪問 http://localhost:8080/swagger-ui.html 體驗(yàn)一下。

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

好吧,出了點(diǎn)小問題,不過不用慌。

出現(xiàn)這個問題的原因是因?yàn)槲覀兗由狭?ResponseBodyAdvice統(tǒng)一處理返回值/響應(yīng)體,導(dǎo)致給Swagger的返回值也包裝了一層,UI頁面無法解析。可以通過 http://localhost:8080/v2/api-docs?group=SwaggerDemo觀察Swagger返回的json數(shù)據(jù)。

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

既然知道了問題原因那就很好解決了,我們只需要在ResponseBodyAdvice處理類中只轉(zhuǎn)換我們自己項(xiàng)目的接口即可。

@RestControllerAdvice(basePackages = "com.jianzh5.blog")
@Slf4j
public class ResponseAdvice implements ResponseBodyAdvice<Object> {
...
}   

通過添加basePackage屬性限定統(tǒng)一返回值的范圍,這樣就不影響Swagger了。

重啟服務(wù)器再次訪問swagger接口地址,就可以看到接口文檔頁面了。

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

 

For input string: “”

Swagger2.9.2有個bug,就是當(dāng)我們參數(shù)實(shí)體有int類型的參數(shù)時,打開Swagger接口頁面時后端會一直提示異常:

java.lang.NumberFormatException: For input string: ""
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Long.parseLong(Long.java:702)
	at java.base/java.lang.Long.valueOf(Long.java:1144)

有兩種解決方案:

給int類型的字段使用@ApiModelPorperty注解時添加example屬性

@ApiModelProperty(value = "年齡",example = "10")
private int age;

去除原swagger中的swagger-models和swagger-annotations,自行引入高版本的annotations和models

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
  <exclusion>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-annotations</artifactId>
  </exclusion>
  <exclusion>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-models</artifactId>
  </exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>

集成Swagger過程中雖然會出現(xiàn)兩個小問題,解決后我們就可以愉快享受Swagger給我們帶來的便利了。

 

Swagger美化

Swagger原生UI有點(diǎn)丑,我們可以借助Swagger的增強(qiáng)工具 knife4j優(yōu)化一下。

第一步: 引入依賴包

<!--整合Knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>

由于knife4j中已經(jīng)帶了 swagger-annotations和 swagger-models的依賴,所以我們可以把上文中手動添加的兩個依賴刪除。

第二步:啟用knife4j增強(qiáng)

@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
@EnableKnife4j
public class SwaggerConfig {
...
}

通過上面兩步我們就完成了Swagger的美化,通過瀏覽器訪問 http://localhost:8080/doc.html 即可看到效果。

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

 

Swagger參數(shù)分組

看到這里的同學(xué)心理肯定會想,就這?這就是老鳥的做法?跟我們新手也沒啥區(qū)別呀

別急,我們先來看一個效果。

首先我們定義了兩個接口,一個新增,一個編輯

@ApiOperation("新增")
@PostMapping(value = "/valid/add")
public String add(@Validated(value = {ValidGroup.Crud.Create.class}) ValidVO validVO){
log.info("validEntity is {}", validVO);
return "test3 valid success";
}

@ApiOperation("更新")
@PostMapping(value = "/valid/update")
public String update(@Validated(value = ValidGroup.Crud.Update.class) ValidVO validVO){
log.info("validEntity is {}", validVO);
return "test4 valid success";
}

注意看,這里用的是同一個實(shí)體 ValidVO來接收前端參數(shù),只不過使用了參數(shù)校驗(yàn)中的分組,然后我們打開kife4j頁面觀察兩者的接口文檔有何不同。

新增:

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

編輯:

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

通過上面可以看到,雖然用于接受參數(shù)的實(shí)體一樣,但是當(dāng)分組不一樣時展示給前端的參數(shù)也不一樣,這就是Swagger的分組功能。

當(dāng)然原生的Swagger是不支持分組功能的,我們需要對Swagger進(jìn)行擴(kuò)展。我已經(jīng)將代碼上傳到了github上,由于代碼量比較多這里就不展示了,大家可以自行查閱。

java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)

引入擴(kuò)展類后還需要在Swagger配置類 SwaggerConfig中注入對應(yīng)的Bean。

@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
@EnableKnife4j
public class SwaggerConfig {
  ...

  @Bean
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupOperationModelsProviderPlugin groupOperationModelsProviderPlugin() {
      return new GroupOperationModelsProviderPlugin();
  }

  @Bean
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupModelBuilderPlugin groupModelBuilderPlugin() {
      return new GroupModelBuilderPlugin();
  }

  @Bean
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupModelPropertyBuilderPlugin groupModelPropertyBuilderPlugin() {
      return new GroupModelPropertyBuilderPlugin();
  }

  @Bean
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupExpandedParameterBuilderPlugin groupExpandedParameterBuilderPlugin() {
      return new GroupExpandedParameterBuilderPlugin();
  }

  @Bean
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupOperationBuilderPlugin groupOperationBuilderPlugin() {
      return new GroupOperationBuilderPlugin();
  }

  @Bean
  @Primary
  @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
  public GroupModelAttributeParameterExpander groupModelAttributeParameterExpander(FieldProvider fields, AccessorsProvider accessors, EnumTypeDeterminer enumTypeDeterminer) {
      return new GroupModelAttributeParameterExpander(fields, accessors, enumTypeDeterminer);
  }


}

 

分組使用說明

1.在bean對象的屬性里配置如下注釋

@Null(groups = ValidGroup.Crud.Create.class)
@NotNull(groups = ValidGroup.Crud.Update.class,message = "應(yīng)用ID不能為空")
@ApiModelProperty(value = "應(yīng)用ID",example = "cloud")
private String appId;

當(dāng)新增場景的時候,appId為空,不需要傳值; 當(dāng)修改場景的時候,appId不能為空,需要傳值 ;其他沒有配置組的皆為默認(rèn)組(Default)

2.在接口參數(shù)的時候加入組規(guī)則校驗(yàn)

@ApiOperation("新增")
@PostMapping(value = "/valid/add")
public String add(@Validated(value = {ValidGroup.Crud.Create.class}) ValidVO validVO){
	log.info("validEntity is {}", validVO);
	return "test3 valid success";
}

當(dāng)前接口會針對默認(rèn)組的bean屬性進(jìn)行校驗(yàn),同時針對保存常見的屬性進(jìn)行校驗(yàn)。

 

小結(jié)

Swagger集成相對來說還是很簡單的,雖然在集成過程中也出現(xiàn)了幾個小問題,不過也很容易就解決了。今天文章的重點(diǎn)內(nèi)容是Swagger分組功能,跟之前的參數(shù)校驗(yàn)文章一樣,很多同學(xué)遇到這種分組場景時往往會選擇創(chuàng)建多個實(shí)體類,雖然也能解決問題,只不過總是有點(diǎn)別扭。

不過遺憾的是,本文中Swagger的分組擴(kuò)展只支持Swagger2,至于新版本Swagger3就不怎么支持了。如果有同學(xué)已經(jīng)擴(kuò)展好了,歡迎給我提pr呀。

以上就是java集成開發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot生成接口文檔的資料請關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://blog.csdn.net/jianzhang11/article/details/119932669

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品亚洲精品日韩已满 | bnb998八度免费影院丫意浓 | 免费永久观看美女视频网站网址 | 亚洲男人天堂2023 | 日韩精品一区二三区中文 | 欧美xxxxx性| 国产一级黄毛片 | 99香蕉网 | 猛h辣h高h文湿重口 门房秦大爷在线阅读 | 短篇同学新婚h系列小说 | 亚洲爱视频 | 久久成人国产精品一区二区 | 趴好撅高打屁股sp调教h | 91麻豆精品国产自产在线观看 | 精品一区二区三区在线视频观看 | 美女张开双腿让男人捅 | 日本国产在线视频 | 国产欧美二区三区 | 国产欧美日韩专区毛茸茸 | 国产日韩欧美在线播放 | 91亚洲视频在线观看 | 77成人影视 | 成在线人免费视频一区二区三区 | 成年人福利 | 婷婷在线成人免费观看搜索 | 国产高清国内精品福利 | 五月天精品在线 | 国产99青草全福视在线 | 精品久久久久久综合网 | 国产福利资源网在线观看 | 国产精品毛片va一区二区三区 | 精品亚洲视频在线观看 | 超h 超重口 高h 污肉1v1 | 极品久久 | 痴mu动漫成年动漫在线观看 | 国产自拍视频一区 | 午夜在线观看免费观看 视频 | 亚洲国产成人精品 | 99热国产这里只有精品99 | 免费观看在线观看 | 亚洲无线一二三四区 |