Spring Boot集成Swagger2

前言:目前互聯網開發市場都流行先後臺真正的分離,後臺提供數據API接口,前臺負責請求數據並渲染。那麼咱們程序猿們在編寫接口的時候,最不方便之處就是寫完接口後須要進行文檔的編寫以及接口的測試。今天就介紹一款將接口文檔編寫和測試合併一塊兒的集大成者Swagger,也是目前不少企業再用的一個API管理工具。此DEMO的開發環境是:MAVEN + Spring Boot 2.1.0 + JDK8 + Swagger2.9.2html

一、快速構建Spring Boot項目

https://start.spring.io/中選...,而後選用Spring Boot2.1.0版本,Group是com.mage,Artifact是swagger_restful,Dependencies選擇web,這樣就能快速構建一個基於Spring Boot的web項目了。以下圖:java

項目構建

二、使用IDEA打開項目

解壓swagger_restful.zip,而後使用idea導入項目,並執行SwaggerRestfulApplication.java,不報錯說明項目構建成功web

啓動項目

三、pom導入swagger2的依賴jar包

<!-- 用於JSON API文檔的生成-->
<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>

其中springfox-swagger2這個jar包是用於JSON API文檔的生成,springfox-swagger-ui用於API文檔界面生成,其餘版本請參考:https://mvnrepository.com/art...://mvnrepository.com/artifact/io.springfox/springfox-swagger-uispring

五、編寫測試的Controller和Model(TestController和Test)

編寫一個Test的數據模型api

package com.mage.swagger_restful.model;

public class Test {
    private Integer id;
    private String content;
    private Integer isValid;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Integer getIsValid() {
        return isValid;
    }

    public void setIsValid(Integer isValid) {
        this.isValid = isValid;
    }
}

基於Restful規則,編寫一組測試的API接口:瀏覽器

package com.mage.swagger_restful.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("test")
public class TestController {

    @GetMapping("")
    public String list() {
        return "查詢列表數據!";
    }

    @GetMapping("{id}")
    public String find(@PathVariable Integer id) {
        return String.format("根據主鍵查詢數據: %d", id);
    }

    @PostMapping("")
    public String add() {
        return "插入數據!";
    }

    @PutMapping("{id}")
    public String update(@PathVariable Integer id) {
        return String.format("根據主鍵更新一條記錄: %d", id);
    }

    @DeleteMapping("{id}")
    public String delete(@PathVariable Integer id) {
        return String.format("根據主鍵刪除記錄: %d", id);
    }
}

由於接口是基於Restful(本文不討論Restful的編寫規範)編寫,因此若是單純利用瀏覽器輸入是無法進行接口測試的,好比模擬post, put或者delete請求,這時要測試能夠藉助一些瀏覽器的插件好比postman或者rested等。這樣咱們還要額外去安裝工具,顯得比較麻煩,同時工做中寫完接口後,通常還會編寫接口文檔,那麼聰明的碼農就想着能不能優化這個流程,讓接口測試和接口文檔編寫變得簡單快捷,因而乎,swagger應用而生。restful

六、代碼中集成Swagger

a) 編寫Swagger的配置類

package com.mage.swagger_restful.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
@ConditionalOnExpression("${swagger.enable:true}")
public class SwaggerConfig {

    @Bean
    public Docket createDocket(){

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder().title("碼歌學院API")
                        .description("碼歌學院相關接口API文檔")
                        .version("1.0").build())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mage"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

}

其中@EnableSwagger2開啓Swagger2功能,是swagger2的註解,@ConditionalOnExpression("${swagger.enable:true}")當配置文件中swagger.enable爲true時才啓用swagger2,是spring boot註解,方便區分不一樣環境下是否啓用swagger2。app

b) 修改application.properties

swagger.enable=true

c) 修改Test實體模型和TestController,添加Swagger對應註解

修改Test實體模型:maven

package com.mage.swagger_restful.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(description = "測試模型實體")
public class Test {
    @ApiModelProperty(name = "id", value = "主鍵", hidden = true)
    private Integer id;
    @ApiModelProperty(name = "content", value = "測試內容")
    private String content;
    @ApiModelProperty(name = "isValid", value = "是否有效0=無效,1=有效", hidden = true)
    private Integer isValid;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Integer getIsValid() {
        return isValid;
    }

    public void setIsValid(Integer isValid) {
        this.isValid = isValid;
    }
}

其中:ide

@ApiModel(description = "測試模型實體")做用在參數實體或者響應實體上,description表明描述信息;

@ApiModelProperty(name = "id", value = "主鍵", hidden = true)做用在實體屬性上,標記屬性名稱和說明內容,name表明屬性名稱,value表示屬性內容,hidden是否所以,默認是false。

修改TestController:

package com.mage.swagger_restful.controller;

import com.mage.swagger_restful.model.Test;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("test")
@Api(tags = "測試API接口")
public class TestController {

    @GetMapping("")
    @ApiOperation(value="獲取列表數據", notes="獲取列表下測試數據")
    public String list() {
        return "查詢列表數據!";
    }

    @GetMapping("{id}")
    @ApiOperation(value="獲取ID數據", notes="根據ID獲取某條測試數據")
    @ApiImplicitParam(name = "id", value = "主鍵id", paramType = "path", required = true)
    public String find(@PathVariable Integer id) {
        return String.format("根據主鍵查詢數據: %d", id);
    }

    @PostMapping("")
    @ApiOperation(value="新增數據")
    @ApiParam(name = "test", value = "添加的測試模型實體")
    public String add(@RequestBody Test test) {
        return "插入數據!";
    }

    @PutMapping("{id}")
    @ApiOperation(value="更新數據", notes="根據ID更新測試數據")
    @ApiImplicitParam(name = "id", value = "主鍵id", paramType = "path", required = true)
    public String update(@PathVariable Integer id, @ApiParam(name = "test", value = "更新的測試模型實體") @RequestBody Test test) {
        return String.format("根據主鍵更新一條記錄: %d", id);
    }

    @DeleteMapping("{id}")
    @ApiOperation(value="刪除數據", notes="根據ID刪除測試數據")
    @ApiImplicitParam(name = "id", value = "主鍵id", paramType = "path", required = true)
    public String delete(@PathVariable Integer id) {
        return String.format("根據主鍵刪除記錄: %d", id);
    }
}

其中:

@Api(tags = "測試API接口")標記controller類是作什麼的,tags表示分類;

@ApiOperation(value="獲取列表數據", notes="獲取列表下測試數據")標記controller下的方法,表示這個接口是作什麼的,value就是說明做用,notes詳細說明;

@ApiImplicitParam(name = "id", value = "主鍵id", paramType = "path", required = true)標記參數,name是參數名,value是參數說明,paramType是參數類型:path(路徑參數),query(查詢參數), body(請求體參數),header(請求頭參數),form(表單提交參數),require表明是否必填,默認是false

@ApiParam(name = "test", value = "更新的測試模型實體")跟@ApiImplicitParam相似,標記參數,不過不一樣的是:

  • 對Servlets或者非 JAX-RS的環境,只能使用 ApiImplicitParam。
  • 在使用上,ApiImplicitParam比ApiParam具備更少的代碼侵入性,只要寫在方法上就能夠了,可是須要提供具體的屬性才能配合swagger ui解析使用。
  • ApiParam只須要較少的屬性,與swagger ui配合更好。

七、瀏覽器輸入地址:http://localhost:8080/swagger-ui.html

瀏覽查看

點開測試API接口就能夠進行測試:

測試API接口

八、注意

若是採用swagger2.9.0時,會出現一個bug,好比我修改一下TestController裏面的find方法

舊方法:

舊方法

新方法:

新方法

這時若是啓動,訪問swagger ui時會出現一個bug:

bug圖片

這個是一個數據類型轉化的錯誤,就是由於我設置了id爲int類型,而swagger默認給的是空字符串,所以就提示錯誤,解決方案有兩種,第一種就是不要寫dataType,第二種就是升級swagger-annotations和models jar包:

a)排除已經依賴的swagger-annotations和models jar包

<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>

b) 引入新的jar包

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

這樣也能完美解決!

相關文章
相關標籤/搜索