最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2021年10月27日 17:22:56   作者:飄渺Jam  
這篇文章主要為大家介紹了java集成開(kāi)發(fā)SpringBoot如何生成接口文檔的示例實(shí)現(xiàn)過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助

大家好,我是飄渺。

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

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

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

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

為什么要用Swagger ?

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

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

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

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

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

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

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

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

跨語(yǔ)言性,支持 40 多種語(yǔ)言。

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

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

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

Swagger集成

集成Swagger很簡(jiǎn)單,只需要簡(jiǎn)單三步。

第一步: 引入依賴包

<!--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 加入配置

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

增加一個(gè)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","jianzh5@163.com"))
                .description("Swagger接口文檔")
                .version(VERSION)
                .build();
    }

}

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

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

第三步,配置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";
    }
}

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

同時(shí)我們給 ValidVO也加上對(duì)應(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 = "級(jí)別不能為空")
    @ApiModelProperty(value = "級(jí)別")
    private String level;

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

}

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

Unable to infer base url

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

image-20210820155105249

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

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

image-20210820165255112

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

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

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

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

image-20210820170634932

For input string: “”

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

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注解時(shí)添加example屬性

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

去除原swagger中的swagger-modelsswagger-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過(guò)程中雖然會(huì)出現(xiàn)兩個(gè)小問(wèn)題,解決后我們就可以愉快享受Swagger給我們帶來(lái)的便利了。

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的依賴,所以我們可以把上文中手動(dòng)添加的兩個(gè)依賴刪除。

第二步:?jiǎn)⒂胟nife4j增強(qiáng)

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

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

image-20210822191542202

Swagger參數(shù)分組

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

別急,我們先來(lái)看一個(gè)效果。

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

@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";
}

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

新增:

image-20210822224030743

編輯:

image-20210822224106495

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

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

image-20210822224422361

引入擴(kuò)展類后還需要在Swagger配置類 SwaggerConfig中注入對(duì)應(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);
    }


}

分組使用說(shuō)明

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

@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)新增場(chǎng)景的時(shí)候,appId為空,不需要傳值; 當(dāng)修改場(chǎng)景的時(shí)候,appId不能為空,需要傳值 ;其他沒(méi)有配置組的皆為默認(rèn)組(Default)

2.在接口參數(shù)的時(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)前接口會(huì)針對(duì)默認(rèn)組的bean屬性進(jìn)行校驗(yàn),同時(shí)針對(duì)保存常見(jiàn)的屬性進(jìn)行校驗(yàn)。

小結(jié)

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

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

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

相關(guān)文章

  • java根據(jù)模板導(dǎo)出PDF的詳細(xì)實(shí)現(xiàn)過(guò)程

    java根據(jù)模板導(dǎo)出PDF的詳細(xì)實(shí)現(xiàn)過(guò)程

    前段時(shí)間因?yàn)橄嚓P(guān)業(yè)務(wù)需求需要后臺(tái)生成pdf文件,所以下面這篇文章主要給大家介紹了關(guān)于java根據(jù)模板導(dǎo)出PDF的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié)(推薦)

    MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié)(推薦)

    這篇文章主要介紹了MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié),需要的朋友可以參考下
    2017-08-08
  • Java應(yīng)用多機(jī)器部署解決大量定時(shí)任務(wù)問(wèn)題

    Java應(yīng)用多機(jī)器部署解決大量定時(shí)任務(wù)問(wèn)題

    這篇文章主要介紹了Java應(yīng)用多機(jī)器部署解決大量定時(shí)任務(wù)問(wèn)題,兩臺(tái)服務(wù)器同時(shí)部署了同一套代碼, 代碼中寫有spring自帶的定時(shí)任務(wù),但是每次執(zhí)行定時(shí)任務(wù)時(shí)只需要一臺(tái)機(jī)器去執(zhí)行,需要的朋友可以參考下
    2019-07-07
  • 解決SpringBoot中使用@Transactional注解遇到的問(wèn)題

    解決SpringBoot中使用@Transactional注解遇到的問(wèn)題

    這篇文章主要介紹了SpringBoot中使用@Transactional注解遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java實(shí)現(xiàn)的小時(shí)鐘示例分享

    java實(shí)現(xiàn)的小時(shí)鐘示例分享

    這篇文章主要介紹了java實(shí)現(xiàn)的小時(shí)鐘示例,需要的朋友可以參考下
    2014-02-02
  • Java 單例模式詳細(xì)解釋

    Java 單例模式詳細(xì)解釋

    這篇文章主要給大家介紹了關(guān)于Java中四種單例模式的相關(guān)資料,其中包括餓漢式、懶漢式、懶漢式(雙重鎖)及內(nèi)部類等四種,分別給出了詳細(xì)的示例代碼和介紹,需要的朋友們下面來(lái)一起看看吧。
    2021-11-11
  • SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例

    SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例

    本文主要介紹了SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java判斷是否為簡(jiǎn)體中文字符的實(shí)現(xiàn)方法

    Java判斷是否為簡(jiǎn)體中文字符的實(shí)現(xiàn)方法

    在應(yīng)用開(kāi)發(fā)中,判斷簡(jiǎn)體中文字符是一個(gè)重要但常被忽視的任務(wù),簡(jiǎn)體中文和繁體中文在字符上有顯著的區(qū)別,因此在某些場(chǎng)景下我們需要判斷輸入的文本是否為簡(jiǎn)體中文,本文將介紹如何使用Java進(jìn)行此判斷,并提供相應(yīng)的代碼示例,幫助開(kāi)發(fā)者更好地理解這一過(guò)程
    2024-09-09
  • Java線程安全與非線程安全解析

    Java線程安全與非線程安全解析

    這篇文章主要介紹了Java線程安全與非線程安全解析,涉及非線程安全現(xiàn)象模擬以及線程安全的實(shí)現(xiàn)等相關(guān)內(nèi)容,需要的朋友可以參考,一起交流學(xué)習(xí)。
    2017-10-10
  • FutureTask為何單個(gè)任務(wù)僅執(zhí)行一次原理解析

    FutureTask為何單個(gè)任務(wù)僅執(zhí)行一次原理解析

    這篇文章主要為大家介紹了FutureTask為何單個(gè)任務(wù)僅執(zhí)行一次原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11

最新評(píng)論

沙洋县| 贵定县| 红原县| 德惠市| 柳林县| 自治县| 奈曼旗| 青岛市| 澜沧| 湖口县| 深水埗区| 信阳市| 蓬安县| 武威市| 江源县| 逊克县| 荥阳市| 宁安市| 砀山县| 确山县| 珲春市| 临清市| 上杭县| 塔河县| 安多县| 赤壁市| 兴国县| 南丰县| 天镇县| 蛟河市| 龙泉市| 鄱阳县| 阿克苏市| 敦煌市| 蛟河市| 余庆县| 榆中县| 惠水县| 仁怀市| 政和县| 邵阳市|