《Spring Boot極簡(jiǎn)教程》第14章 Spring Boot集成Swagger2構(gòu)建自動(dòng)化Rest API文檔

第14章 Spring Boot集成Swagger2構(gòu)建自動(dòng)化Rest API文檔

Swagger2的API文檔

在以往的項(xiàng)目中糯俗,關(guān)于API接口文檔,我們一般使用wiki或者干脆就是“線下文檔”徐伐。缺點(diǎn)是很明顯的:在迭代開發(fā)過程中,API會(huì)頻繁變動(dòng)募狂,這樣文檔需要同步修改办素。繁瑣。如果不及時(shí)更新祸穷,就會(huì)出生調(diào)用方?jīng)]有及時(shí)了解到API簽名的變化性穿,導(dǎo)致較大的溝通很改動(dòng)成本。

微服務(wù)時(shí)代雷滚,效率第一需曾。

使用Swagger可以在部署的時(shí)候,實(shí)時(shí)生成最新的在線API文檔祈远,而且不僅僅是文檔濒生,同時(shí)支持API接口的測(cè)試。

我們使用Swagger代虾,只需要在我們的開發(fā)代碼中屈尼,加上少量的注解配置,即可 自動(dòng)化構(gòu)建Rest API文檔躬充。在多人協(xié)作的開發(fā)過程中逃顶,API文檔不僅可以減少等待,也能保證開發(fā)的持續(xù)進(jìn)行充甚。有一些單元測(cè)試框架可以生成API文檔以政,而Swagger可以在不寫單元測(cè)試的情況下生成在線的API頁面,并且可以直接在頁面進(jìn)行API調(diào)試伴找。

SpringBoot集成Swagger2步驟

1.添加工程依賴的jar

在build.gradle中添加swagger2的依賴:

    // https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
    compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.1'
   // https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
    compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.1'

完整的build.gradle配置如下:

group 'com.easy.springboot'
version '1.0-SNAPSHOT'

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'org.springframework.boot'

sourceCompatibility = 1.8

repositories {
//    mavenCentral()
//    jcenter()
    maven {
        url 'http://maven.aliyun.com/nexus/content/groups/public/'
    }

}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    testCompile group: 'junit', name: 'junit', version: '4.12'

    compile('org.springframework.boot:spring-boot-starter-web')
    
    // https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
    compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.1'
   // https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
    compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.1'

}

buildscript {
    ext {
        springBootVersion = '1.5.2.RELEASE'
    }
    repositories {
//        mavenCentral()
//        jcenter()
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

2.配置Swagger的Docket Bean

@Configuration
class SwaggerConfig {

    /**
     * Docket: Springfox’s, primary api configuration mechanism is initialized for swagger specification 2.0
     *
     * A builder which is intended to be the primary interface into the swagger-springmvc framework.
     * Provides sensible defaults and convenience methods for configuration.
     * @return
     */
    @Bean
    Docket myApi() {

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.easy.springboot.h5perf"))
//                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build()

    }

    def apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot集成Swagger2構(gòu)建自動(dòng)化Rest API文檔")
                .description("Spring Boot開發(fā)從0到1教程")
                .version("1.0")
                .build()
    }
}

這個(gè) Docket類盈蛮,是Springfox 框架的API配置機(jī)制實(shí)現(xiàn)的builder類。

我們通過@Configuration標(biāo)記此類為配置類技矮,會(huì)在SpringBoot項(xiàng)目啟動(dòng)的時(shí)候加載抖誉,
實(shí)際上我們已經(jīng)完成了對(duì)Swagger的配置殊轴,Swagger會(huì)自動(dòng)掃描我們配置的cn.com.wenyi.controller包下的接口自動(dòng)生成接口文檔。

3.配置WebMvc的addResourceHandlers

package com.easy.springboot.h5perf.config

import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter

/**
 * Created by jack on 2017/4/23.
 * http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.EnableWebMvcConfiguration.html
 */

@Configuration
class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/")

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/")
    }


}

4.Swagger的API注解在Controller上面的使用

package com.easy.springboot.h5perf.controller

import com.easy.springboot.h5perf.mapper.TestCaseMapper
import com.easy.springboot.h5perf.model.TestCase
import com.easy.springboot.h5perf.result.Result
import groovy.json.JsonOutput
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiOperation
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody
import springfox.documentation.swagger2.annotations.EnableSwagger2

/**
 * Created by jack on 2017/4/22.
 * http://springfox.github.io/springfox/docs/current/#springfox-samples
 */
@Api(value = "測(cè)試任務(wù)管理", tags = ["測(cè)試任務(wù)管理API"], description = "描述信息")
@Controller
class TestCaseController {
    @Autowired
    TestCaseMapper testCaseMapper

    @PostMapping("/saveTestCase")
    @ResponseBody
    def saveTestCase(TestCase testCase) {
        testCase.gmtCreated = new Date()
        println("testCase===" + testCase)
        int insert = testCaseMapper.insert(testCase)
        println("testCase===" + testCase)
        Result result = new Result()
        if (insert == 1) {
            result.success = true
            result.result = testCase
        } else {
            result.success = false
            result.result = testCase
        }
        def jsonOutput = new JsonOutput()
        println("saveTestCase result===" + jsonOutput.toJson(result))
        result
    }

    @GetMapping("/listTestCase")
    def listTestCase(Model model) {
        model.addAttribute("testCaseList", testCaseMapper.findAll())
        "/test_case/list"
    }

    @ApiOperation(value = "list all TestCase Json", notes = "listTestCaseJson", produces = "application/json")
    @GetMapping("/listTestCaseJson")
    @ResponseBody
    def listTestCaseJson() {
        testCaseMapper.findAll()
    }

    @ApiOperation(value = "findOne TestCase Json", notes = "findOne TestCase", produces = "application/json")
    @ApiImplicitParam(name = "id",
            value = "測(cè)試任務(wù)ID",
            dataType = "Integer",//This can be the class name or a primitive
            required = true,
            paramType = "query")//Valid values are {@code path}, {@code query}, {@code body}, {@code header} or {@code form}
    @GetMapping("/findOne")
    @ResponseBody
    def findOne(@RequestParam(value = "id", required = true) Integer id) {
        testCaseMapper.findOne(id)
    }


}

@API表示這個(gè)類提供一個(gè)開放的API袒炉,可以通過description簡(jiǎn)要描述該API的功能旁理。
在一個(gè)@API下,可有多個(gè)@ApiOperation我磁,表示針對(duì)該API的CRUD操作孽文。

在ApiOperation Annotation中可以通過value,notes描述該操作的作用夺艰,response描述正常情況下該請(qǐng)求的返回對(duì)象類型芋哭。 在一個(gè)ApiOperation下,可以通過ApiResponses描述該API操作可能出現(xiàn)的異常情況郁副。

ApiParam用于描述該API操作接受的參數(shù)類型

我們也可以為項(xiàng)目的Model對(duì)象添加Swagger Annotation减牺,這樣Swagger Scanner可以獲取更多關(guān)于Model對(duì)象的信息。但是存谎,這樣感覺侵入的代碼有點(diǎn)多拔疚。酌情考慮。

5.啟動(dòng)@EnableSwagger2

在Application.groovy 微服務(wù)程序入口類上添加注解@EnableSwagger2:

package com.easy.springboot.h5perf

import org.springframework.boot.CommandLineRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.ComponentScan
import org.springframework.web.servlet.config.annotation.EnableWebMvc
import springfox.documentation.swagger2.annotations.EnableSwagger2

/**
 * Created by jack on 2017/4/22.
 */
@SpringBootApplication
@EnableWebMvc
@EnableSwagger2
@ComponentScan("com.easy.springboot.h5perf")
//@MapperScan('com.easy.springboot.h5perf.mapper') // 此處注解愕贡,與在Mapper接口上添加@Mapper注解功能等效
class Application implements CommandLineRunner {
    static void main(String[] args) {
        SpringApplication.run(Application.class, args)
    }

    @Override
    void run(String... args) throws Exception {


    }
}

@EnableSwagger2這個(gè)注解用來啟動(dòng)Swagger的文檔配置功能草雕,我們通過源碼可以看到,它Import了配置類Swagger2DocumentationConfiguration固以。

而Swagger2DocumentationConfiguration類又@Import了SpringfoxWebMvcConfiguration墩虹,SwaggerCommonConfiguration配置類。到最后憨琳,SpringfoxWebMvcConfiguration類Import了配置類ModelsConfiguration诫钓。

Swagger具體的實(shí)現(xiàn)原理,可以參考[1]~[6]篙螟。

6.運(yùn)行測(cè)試

文檔展示

實(shí)時(shí)測(cè)試

小結(jié)

Swagger可以充當(dāng)前后端協(xié)同工作菌湃,自由聯(lián)調(diào)的重要橋梁。方便快捷遍略。很實(shí)用惧所。

使用Swagger,我們可以自由生產(chǎn)绪杏,顯示和消費(fèi)自己的RESTful服務(wù)下愈。不需要代理和第三方服務(wù)。同時(shí)蕾久,集成swagger-ui势似,通過Swagger API動(dòng)態(tài)的生成漂亮的文檔和API測(cè)試空間。

參考資料:
1.http://springfox.github.io/springfox/docs/current/#springfox-configuration-and-demo-applications
2.http://swagger.io/
3.https://github.com/martypitt/swagger-springmvc
4.https://github.com/swagger-api/swagger-ui
5.https://github.com/swagger-api/swagger-core
6.https://github.com/swagger-api/swagger-spec

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市履因,隨后出現(xiàn)的幾起案子障簿,更是在濱河造成了極大的恐慌,老刑警劉巖栅迄,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件站故,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡霞篡,警方通過查閱死者的電腦和手機(jī)世蔗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門端逼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朗兵,“玉大人,你說我怎么就攤上這事顶滩∮嘁矗” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵礁鲁,是天一觀的道長(zhǎng)盐欺。 經(jīng)常有香客問我,道長(zhǎng)仅醇,這世上最難降的妖魔是什么冗美? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮析二,結(jié)果婚禮上粉洼,老公的妹妹穿的比我還像新娘。我一直安慰自己叶摄,他們只是感情好属韧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛤吓,像睡著了一般宵喂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上会傲,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天锅棕,我揣著相機(jī)與錄音,去河邊找鬼淌山。 笑死裸燎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的艾岂。 我是一名探鬼主播顺少,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了脆炎?” 一聲冷哼從身側(cè)響起梅猿,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秒裕,沒想到半個(gè)月后袱蚓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡几蜻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年喇潘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梭稚。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡颖低,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弧烤,到底是詐尸還是另有隱情忱屑,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布暇昂,位于F島的核電站莺戒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏急波。R本人自食惡果不足惜从铲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澄暮。 院中可真熱鬧名段,春花似錦、人聲如沸赏寇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗅定。三九已至自娩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渠退,已是汗流浹背忙迁。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碎乃,地道東北人姊扔。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像梅誓,于是被迫代替她去往敵國(guó)和親恰梢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佛南,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容