Spring Boot集成swagger2生成接口文檔

在我們的傳統(tǒng)項(xiàng)目中仍稀,對(duì)前后端的API接口約定夺荒,一般有寫(xiě)成接口文檔,或者公司內(nèi)部口頭交流歪脏,或者其它方式疑俭,但這幾種方式都給我們的協(xié)同工作中帶來(lái)了或多或少的不便之處,那么就有了一些工具的出現(xiàn)來(lái)對(duì)我們的協(xié)同工作帶來(lái)便利婿失。這種工具選擇面還是挺多的钞艇,有swagger啄寡,jdoc,apiDoc等香璃。

目前我在工作中寫(xiě)得較多的就是API接口这难,項(xiàng)目大部分都采用springBoot編寫(xiě),集成了swagger2來(lái)作為生成API+測(cè)試葡秒,總體上挺好使用的姻乓,話不多說(shuō),直接步入正題眯牧。

一蹋岩、依賴包引入

pom.xml中引人依賴

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

二、配置

2.1 在springBoot配置文件application.yml中加入如下配置:

#swagger 配置
swagger: 
  title: API示例
  desc: 基于springBoot編寫(xiě)的RESful-API
  version: 0.0.1.SNAPSHOT
  termsOfServiceUrl: javascript:void(0)
  license: Apache 2.0
  licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.html
  basePackage: com.restful.api.demo.web
  groupName: 默認(rèn)API示例分組
  contactName: wendell
  contactUrl: https://github.com/wendell-dev/restful-api-demo.git
  contactEmail: wendell-dev@foxmail.com

2.2 新建配置類

類頭部主要聲明了配置注解和啟用swagger2注解

/**
 * 對(duì)Swagger2的配置信息
 * 
 * @author wendell
 */
@Configuration
@EnableSwagger2
@ConfigurationProperties(prefix = "swagger")
public class Swagger2Config {
    private String title;
    private String desc;
    private String version;
    private String termsOfServiceUrl;
    private String license;
    private String licenseUrl;
    private String basePackage;
    private String groupName;
    private String contactName;
    private String contactUrl;
    private String contactEmail;

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title(title).description(desc).version(version).termsOfServiceUrl(termsOfServiceUrl)
                .licenseUrl(licenseUrl).license(license).contact(new Contact(contactName, contactUrl, contactEmail))
                .build();
    }

    @Bean
    public Docket swaggerApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(groupName)
                .directModelSubstitute(LocalDate.class, String.class).genericModelSubstitutes(ResponseEntity.class)
                .useDefaultResponseMessages(false)
                .globalResponseMessage(RequestMethod.POST, customerResponseMessage())
                .globalResponseMessage(RequestMethod.GET, customerResponseMessage())
                .forCodeGeneration(true).select()
                .apis(RequestHandlerSelectors.basePackage(basePackage))
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
                .build();
    }

    private List<ResponseMessage> customerResponseMessage() {
        List<ResponseMessage> list = new ArrayList<>();
        list.add(new ResponseMessageBuilder().code(200).message("請(qǐng)求成功").build());
        list.add(new ResponseMessageBuilder().code(201).message("資源創(chuàng)建成功").build());
        list.add(new ResponseMessageBuilder().code(204).message("服務(wù)器成功處理了請(qǐng)求学少,但不需要返回任何實(shí)體內(nèi)容").build());
        list.add(new ResponseMessageBuilder().code(400).message("請(qǐng)求失敗,具體查看返回業(yè)務(wù)狀態(tài)碼與對(duì)應(yīng)消息").build());
        list.add(new ResponseMessageBuilder().code(401).message("請(qǐng)求失敗,未經(jīng)過(guò)身份認(rèn)證").build());
        list.add(new ResponseMessageBuilder().code(405).message("請(qǐng)求方法不支持").build());
        list.add(new ResponseMessageBuilder().code(415).message("請(qǐng)求媒體類型不支持").build());
        list.add(new ResponseMessageBuilder().code(500).message("服務(wù)器遇到了一個(gè)未曾預(yù)料的狀況,導(dǎo)致了它無(wú)法完成對(duì)請(qǐng)求的處理").build());
        list.add(new ResponseMessageBuilder().code(503).message("服務(wù)器當(dāng)前無(wú)法處理請(qǐng)求,這個(gè)狀況是臨時(shí)的剪个,并且將在一段時(shí)間以后恢復(fù)").build());
        return list;
    }

    //  setter/getter略
}

三、controller中使用

需要在controller層的類頭部以及方法頭部侵入代碼了版确,主要用到一些io.swagger.annotations下的注解

/**
 * 測(cè)試接口 - controller類
 *
 * @author wendell
 */
@Api(tags = "測(cè)試接口")
@RestController
@RequestMapping(value = "/tests")
public class TestController {

    @ApiOperation(value = "測(cè)試 - GET請(qǐng)求參數(shù)")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "編號(hào)", required = true, paramType = "query"),
        @ApiImplicitParam(name = "name", value = "名稱", required = false, paramType = "query") 
    })
    @GetMapping
    public ResponseEntity<String> test(@RequestParam Long id, @RequestParam String name) {
        return ResponseEntity.ok("編號(hào): " + id + "名稱: " + name);
    }

}
    

四扣囊、啟動(dòng)springBoot應(yīng)用

接著我們啟動(dòng)我們的springBoot應(yīng)用,訪問(wèn)swagger2自帶的入口頁(yè)面地址 http://localhost/swagger-ui.html , 下圖就是生成的API接口绒疗,可以點(diǎn)擊左下方的 [Try it out!] 按鈕進(jìn)行http請(qǐng)求測(cè)試侵歇,非常方便。

swagger-ui

五吓蘑、加入統(tǒng)一參數(shù)

大部分時(shí)候惕虑,我們編寫(xiě)的API接口都需要登錄后訪問(wèn),一般我們都是統(tǒng)一驗(yàn)證請(qǐng)求header里面的token參數(shù)磨镶,那么類似這種參數(shù)就應(yīng)該統(tǒng)一處理溃蔫,而不是在所有需要的controller方法中都加上token參數(shù),類似下面這種 不恰當(dāng) 用法:

@ApiOperation(value = "測(cè)試 - GET請(qǐng)求加入header參數(shù)")
@ApiImplicitParams({
    @ApiImplicitParam(name = "token", value = "請(qǐng)求token", required = true, paramType = "header"),
})
@GetMapping
public ResponseEntity<String> test(@RequestHeader String token) {
    return ResponseEntity.ok("token:" + token);
}

我們應(yīng)該在swagger的配置類中統(tǒng)一處理token參數(shù)琳猫,只需要修改我們上面2.2步驟中Swagger2Config類即可伟叛,如下這樣的方式:

@Bean
public Docket swaggerApi() {
    //  ==================== 需要的參數(shù) START ==================== 
    List<Parameter> pars = new ArrayList<>();
    ParameterBuilder token = new ParameterBuilder();
    token.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
    pars.add(token.build());
    //  ==================== 需要的參數(shù) END ==================== 
    return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(groupName)
            .globalOperationParameters(pars) // 全局參數(shù)
            .directModelSubstitute(LocalDate.class, String.class).genericModelSubstitutes(ResponseEntity.class)
            .useDefaultResponseMessages(false)
            .globalResponseMessage(RequestMethod.POST, customerResponseMessage())
            .globalResponseMessage(RequestMethod.GET, customerResponseMessage())
            .forCodeGeneration(true).select()
            .apis(RequestHandlerSelectors.basePackage(basePackage))
            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
            .build();
}

接下來(lái)我們?cè)俅卧L問(wèn)swagger2自帶的入口頁(yè)面地址,看看效果:


swagger-ui

可以看見(jiàn)沸移,我們的接口中已經(jīng)多了一個(gè)非必填的參數(shù)token痪伦,而且參數(shù)是在請(qǐng)求header中。

六雹锣、結(jié)束語(yǔ)

好了网沾,關(guān)于springBoot集成swagger2的方式就介紹到這里,文中介紹的方式絕大部分方式都是基于我自己在工作中的使用方式蕊爵,已經(jīng)能夠滿足大部分的接口文檔需求了辉哥。 當(dāng)然還有一些高級(jí)點(diǎn)的特征沒(méi)有介紹到,如分組之類,其實(shí)就是在配置文件上下文章醋旦,需要的時(shí)候自行g(shù)oogle一下即可恒水。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市饲齐,隨后出現(xiàn)的幾起案子钉凌,更是在濱河造成了極大的恐慌,老刑警劉巖捂人,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件御雕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡滥搭,警方通過(guò)查閱死者的電腦和手機(jī)酸纲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瑟匆,“玉大人闽坡,你說(shuō)我怎么就攤上這事〕盍铮” “怎么了疾嗅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)冕象。 經(jīng)常有香客問(wèn)我宪迟,道長(zhǎng),這世上最難降的妖魔是什么交惯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮穿仪,結(jié)果婚禮上席爽,老公的妹妹穿的比我還像新娘。我一直安慰自己啊片,他們只是感情好只锻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著紫谷,像睡著了一般齐饮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笤昨,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天祖驱,我揣著相機(jī)與錄音,去河邊找鬼瞒窒。 笑死捺僻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匕坯,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼束昵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了葛峻?” 一聲冷哼從身側(cè)響起狞谱,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎塔沃,沒(méi)想到半個(gè)月后宇弛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腰耙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年榛丢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挺庞。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晰赞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出选侨,到底是詐尸還是另有隱情掖鱼,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布援制,位于F島的核電站戏挡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晨仑。R本人自食惡果不足惜褐墅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洪己。 院中可真熱鬧妥凳,春花似錦、人聲如沸答捕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拱镐。三九已至艘款,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沃琅,已是汗流浹背哗咆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阵难,地道東北人岳枷。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親空繁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子殿衰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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