Spring Boot之整合Swagger

前言

經(jīng)過之前文章的學習,我們學會了:

有了這些基礎(chǔ)知識,可以說,我們已經(jīng)擁有Spring Boot項目開發(fā)的入門基礎(chǔ)了。

現(xiàn)實場景中,我們往往需要知道API的文檔,才能用于測試、交付等,土一點的做法是開發(fā)人員編寫API文檔,如Wiki、Word、其他在線文檔等,實際上,有很多開源資源幫我們從技術(shù)上實現(xiàn)了API規(guī)格的文檔化,而Swagger是Spring Boot生態(tài)中的佼佼者,也是官方推薦的。

Swagger的主要優(yōu)點有:

  1. 免費開源,并且官網(wǎng)提供了豐富的工具和文檔介紹;
  2. 通過代碼添加注解,自動生成API文檔;
  3. 提供在線API文檔,API文檔隨API變化而自動同步更新;
  4. 可開啟UI界面,界面美觀、清晰;
  5. UI界面支持在線測試API;
  6. 支持多種語言(Java,PHP...);
  7. 采用OpenAPI 規(guī)范;
    (OpenAPI定義了RESTful APIs的編寫規(guī)范。規(guī)范中指定了一套模式/模型。這套規(guī)范是Swagger為各種編程語言編寫的服務(wù)提供接口文檔奠定了基礎(chǔ)。)
  8. ...

那么,我們今天就一起來學習:

Spring Boot中通過Swagger來做API文檔。

本文使用的項目代碼,是基于上一篇文章使用的Spring Boot項目:
Spring Boot數(shù)據(jù)庫交互之Mybatis

主要步驟

  1. 添加依賴;
  2. 創(chuàng)建config包;
  3. 創(chuàng)建配置類;
  4. 編寫配置類;
  5. 修飾Controller;
  6. 修飾項目啟動類;
  7. 啟動項目、使用Swagger;

1.添加依賴;

//在pom.xml文件中的dependencies節(jié)點內(nèi)添加以下內(nèi)容:
<dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
</dependency>
<dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
</dependency>

2.創(chuàng)建config包;

項目根目錄下創(chuàng)建config包:

config包

3.創(chuàng)建配置類;

配置類

4.編寫配置類;

1. 編寫Swagger配置類;

該步驟的意義:

配置Swagger要掃描API的Controller位置、要顯示的API path的樣式、初始化的Swagger頁面的一些基礎(chǔ)信息(見apiInfo()方法);

  • 特別注意,要使用@EnableSwagger2注解;

  • 設(shè)置生成API接口信息的被掃描Controller路徑,常見寫法:

//生成指定包下的所有API接口信息
RequestHandlerSelectors.basePackage("com.mycompany.sample.controller")
//生成所有API接口
RequestHandlerSelectors.any()
//所有API接口都不生成
RequestHandlerSelectors.none()
//只生成被@Api 這個注解注解過的類接口
RequestHandlerSelectors.withClassAnnotation(Api.class)
//只生成被@ApiOperation 這個注解注解過的API接口
RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)
  • 設(shè)置API路徑篩選規(guī)則,常見寫法有:

//所有API均允許生成
PathSelectors.any()
//所有API均不允許生成
PathSelectors.none()
//正則表達式匹配,匹配上則允許生成,如包含getLead的API:
PathSelectors.regex("^(?!getLead).*$")
//只掃描指定的路徑下的請求,如只想掃描getLead API路徑下的:
//getLead為API path的一部分
PathSelectors.ant("/getLead/**")

代碼如下:

package com.mycompany.sample.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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author : dylanz
 * @since : 07/17/2020
 **/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {//名字不限
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(true)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mycompany.sample.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {//名字不限
        Contact contact = new Contact("Dylan Zhang", "http://www.itdecent.cn/u/56578a39a99a", "997604787@qq.com");
        return new ApiInfoBuilder()
                .title("Lead API")
                .contact(contact)
                .description("Lead related operations")
                .termsOfServiceUrl("http://127.0.0.1:8080/getLead/10130546")
                .version("1.0")
                .build();
    }
}
  • 如果想關(guān)閉Swagger UI:

enable設(shè)置為:.enable(false),之后訪問Swagger UI時就會如下:

關(guān)閉Swagger UI

2. 編寫WebMvcConfig配置類;

該步驟的意義:覆蓋、重寫項目配置的(如有)、默認的靜態(tài)資源路徑,這樣才能讀取到Swagger jar包內(nèi)的靜態(tài)文件(html、css文件等);

package com.mycompany.sample.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.annotation.PostConstruct;

/**
 * @author : dylanz
 * @since : 07/17/2020
 **/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @PostConstruct
    public void init() {
        System.out.println("Init in WebMvcConfig...");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/statics/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

5.修飾Controller;

package com.mycompany.sample.controller;

import com.mycompany.sample.domain.Lead;
import com.mycompany.sample.service.LeadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@RestController
@Api
public class LeadController {
    @Autowired
    private LeadService leadService;

    @GetMapping("/getLead/{leadId}")
    @ResponseBody
    @ApiOperation(value = "get lead by leadId", httpMethod = "GET")
    @ApiImplicitParams(
            {@ApiImplicitParam(name = "leadId", value = "leadId", required = true, paramType = "path", dataType = "Long", example = "10130546")}
    )
    public Lead getLead(@PathVariable(name = "leadId") Long leadId) {
        return leadService.getLeadByLeadId(leadId);
    }
}
1. @Api 注解用來描述該服務(wù)的信息,如果不使用則顯示類名稱;
2. @ApiOperation 注解用于描述接口信息;
3. @ApiParam,@ApiImplicitParam,@ApiImplicitParams 注解用于描述接口的參數(shù);
4. @ApiResponse,@ApiResponses 注解用于描述API返回的信息,不使用會使用默認的、根據(jù)接口情況自動生成的描述信息,可在此處自定義錯誤返回信息,如:

@ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),

5. @ApiVersion 注解用于描述接口的版本信息;

6.修飾項目啟動類;

特別注意,只增加使用@EnableSwagger2注解即可;

package com.mycompany.sample;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@SpringBootApplication
@EnableSwagger2
@MapperScan(basePackages = "com.mycompany.sample.dao")
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

7.啟動項目、使用Swagger;

  • 啟動項目;

啟動項目
  • 訪問Swagger UI;

Swagger UI HTML站點:http://localhost:8080/swagger-ui.html

HTML站點

頁面組成:

1. 標題;
2. API文檔JSON入口:http://localhost:8080/v2/api-docs
3. 作者信息;
4. API文檔主體;
5. 等。

打開折疊的API列表,我們能看到API的規(guī)格:

API規(guī)格

以及API使用的實體對象信息:

實體對象信息

我們還可以編輯實體類,修改、細化實體的展示:

package com.mycompany.sample.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel
public class Lead implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "leadId", dataType = "Long", name = "id", example = "10130546")
    private Long leadId;
    @ApiModelProperty(value = "email", dataType = "String", name = "email", example = "dylan.zhang@xxxx.com")
    private String email;
}

@ApiModel:生成swagger時掃描的實體注解;
@ApiModelProperty:屬性注解,可用于描述實體屬性;

修改后,效果如下:

實體注解

還有我特別喜歡的測試API的功能

1. 點擊API規(guī)格右上角的"Try it out"按鈕:

Try it out

2. 點擊Execute按鈕,測試API:

Execute

3. API測試返回:

API返回

我們可以在頁面上修改API參數(shù),如本例為leadId,進行不同參數(shù)值的測試(Request Body也支持),而不需要其他測試工具或測試代碼,相當方便;

(本例中,我們在controller內(nèi)@ApiImplicitParam注解中設(shè)置了默認值:example = "10130546")

使用Swagger來管理API文檔是十分方便、快捷的,界面美觀、并且有測試API的功能,對開發(fā)人員、測試人員十分友好,滿足了絕大多數(shù)API文檔化的需求。
凡事也要從不同的角度來看待,Swagger強大的背后,也有其一定的局限性:
  1. 僅對于Restful API支持較為友好,其他類型的API支持得不是很好;
  2. 對代碼有一定的侵入性;
  3. Swagger與代碼需要強綁定;
    (每個API都需要人為添加注解,如果有人偷懶,在API開發(fā)時沒有加上Swagger對應(yīng)的注解,那么Swagger UI上是看不到該API的)
  4. ...
綜合來看,我還是很喜歡Swagger的,使用簡單,功能強大!!!

你Get到了嗎?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容