SpringBoot之整合Swagger2

一米碰、問(wèn)題描述

隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展窝革,現(xiàn)在的網(wǎng)站架構(gòu)基本都由原來(lái)的后端渲染,變成了:前端渲染吕座、先后端分離的形態(tài)虐译,而且前端技術(shù)和后端技術(shù)在各自的道路上越走越遠(yuǎn)。 前端和后端的唯一聯(lián)系吴趴,變成了API接口漆诽;API文檔變成了前后端開(kāi)發(fā)人員聯(lián)系的紐帶,變得越來(lái)越重要锣枝,swagger就是一款讓你更好的書(shū)寫(xiě)API文檔的框架厢拭,而且swagger可以完全模擬http請(qǐng)求,入?yún)⒊鰠⒑蛯?shí)際情況差別幾乎為零撇叁。

沒(méi)有API文檔工具之前供鸠,大家都是手寫(xiě)API文檔的(維護(hù)起來(lái)相當(dāng)困難),在什么地方書(shū)寫(xiě)的都有陨闹,有在confluence上寫(xiě)的楞捂,有在對(duì)應(yīng)的項(xiàng)目目錄下readme.md上寫(xiě)的,每個(gè)公司都有每個(gè)公司的玩法趋厉,無(wú)所謂好壞泡一。但是能稱(chēng)之為“框架”的,估計(jì)也只有swagger了

二觅廓、使用步驟

  1. 創(chuàng)建springboot項(xiàng)目配置pom.xml
<dependency>
            <!--添加lombok就可以不用再寫(xiě)set鼻忠,get方法-->
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
  1. 配置啟動(dòng)類(lèi)
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

  1. 創(chuàng)建Swagger的配置類(lèi)
package com.example.config;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Autowired
    Environment environment;
    //配置Docket以配置Swagger具體參數(shù)

    //在不同生產(chǎn)模式下的操作,
//    @Bean
//    public Docket docket(){
//        Profiles profiles=Profiles.of("dev","test");
//        boolean isEnable = environment.acceptsProfiles(profiles);
//        return new Docket(DocumentationType.SWAGGER_2)
//                .ignoredParameterTypes(Integer.class,Long.class, HttpSession.class)
//                .enable(isEnable);
//    }


//    @Bean
//    public Docket docketUser(){
//        Parameter token= new ParameterBuilder().name("token")
//                .description("用戶(hù)登錄令牌")
//                .parameterType("header")
//                .modelRef(new ModelRef("String"))
//                .required(true)
//                .build();
//        List<Parameter> parameters=new ArrayList<>();
//        parameters.add(token);
//        return new Docket(DocumentationType.SWAGGER_2)
//                .globalOperationParameters(parameters);
//    }


    //基于包
    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
//        return new Docket(DocumentationType.SWAGGER_2)
//                .select()
//                .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
//                //paths可以進(jìn)行篩選想要的方法
//                .paths(PathSelectors.ant("/hello/**"))
//                .build();
    }

    //基于方法
//    @Bean
//    public Docket docket(){
//        return new Docket(DocumentationType.SWAGGER_2)
//                .select()
//                .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)).build();
//    }

    private ApiInfo apiInfo(){
        Contact contact=new Contact("小謝","aaa.com","1787798327@qq.com");
        return new ApiInfo("Swagger學(xué)習(xí)接口文檔",
                "這是學(xué)習(xí)swagger時(shí)生成的文檔信息",
                "v1.0",
                "http://xietongxue.top:8090",
                contact,
                "",
                "",
                new ArrayList<>()
        );
    }



}

1
  1. 創(chuàng)建User
package com.example.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用戶(hù)實(shí)體")
public class User {
    @ApiModelProperty(value = "用戶(hù)id",example = "0")
    private Integer id;
    @ApiModelProperty("用戶(hù)名")
    private String username;
    @ApiModelProperty(value = "用戶(hù)年齡",example = "1")
    private String age;
}
  1. 創(chuàng)建Controller
package com.example.controller;

import com.example.model.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

@Api(tags = "用戶(hù)相關(guān)的請(qǐng)求")
@RestController
@RequestMapping("/user")
public class UserController {

    @ApiOperation("獲取用戶(hù)信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用戶(hù)名",
                    dataType = "string",paramType = "header",defaultValue = "zhangsan",example = "lisi"),
            @ApiImplicitParam(name = "password",value = "用戶(hù)密碼")
    })

    @GetMapping
    public String getUser(String username,String password){
        return "user";
    }

    @ApiOperation("添加用戶(hù)")
    @PostMapping
    public User postUser(User user){
        return user;
    }

    @ApiOperation("刪除用戶(hù)")
    @DeleteMapping
    public User delUser(@RequestBody User user){
        return user;
    }




//    @GetMapping
//    public String getUser(){
//        return "張三";
//    }
//
//    @PostMapping
//    public String addUser(String username){
//        return username;
//    }
//
//    @DeleteMapping
//    public User delUser(){
//        User zs = new User("張三", "15");
//        return zs;
//    }
//
//    @PutMapping
//    public String putUser(@RequestBody User user){
//        return "user";
//    }
}

2
  1. 啟動(dòng)測(cè)試http://localhost:8080/swagger-ui.html
    在這里插入圖片描述

部分代碼精講

除了通過(guò)包路徑配置掃描接口外杈绸,還可以通過(guò)配置其他方式掃描接口帖蔓,這里注釋一下所有的配置方式:

any() // 掃描所有,項(xiàng)目中的所有接口都會(huì)被掃描到
none() // 不掃描接口
withMethodAnnotation(final Class<? extends Annotation> annotation)// 通過(guò)方法上的注解掃描瞳脓,如withMethodAnnotation(GetMapping.class)只掃描get請(qǐng)求
withClassAnnotation(final Class<? extends Annotation> annotation) // 通過(guò)類(lèi)上的注解掃描塑娇,如.withClassAnnotation(Controller.class)只掃描有controller注解的類(lèi)中的接口
basePackage(final String basePackage) // 根據(jù)包路徑掃描接口

1、配置接口掃描過(guò)濾
上述方式可以通過(guò)具體的類(lèi)劫侧、方法等掃描接口埋酬,還可以配置如何通過(guò)請(qǐng)求路徑配置:

eturn new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller"))
                // 配置如何通過(guò) path過(guò)濾 即這里只掃描 請(qǐng)求以 /user開(kāi)頭的接口
               .paths(PathSelectors.ant("/user/**"))
                .build();

這里的可選值還有:

any() // 任何請(qǐng)求都掃描
none() // 任何請(qǐng)求都不掃描
regex(final String pathRegex) // 通過(guò)正則表達(dá)式控制哨啃,返回true掃描,false不掃描
ant(final String antPattern) // 通過(guò)ant()表達(dá)式控制写妥,返回true掃描拳球,false不掃描

2、配置要忽略的請(qǐng)求參數(shù)
可以通過(guò)ignoredParameterTypes()方法去配置要忽略的參數(shù):

// 配置docket以配置Swagger具體參數(shù)
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
            // 配置要忽略的參數(shù)
                .ignoredParameterTypes(HttpServletRequest.class) 
                .select()
       .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }


3珍特、配置是否啟動(dòng)Swagger
通過(guò)enable()方法配置是否啟用swagger祝峻,如果是false,swagger將不能在瀏覽器中訪問(wèn)了:

@Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .ignoredParameterTypes(HttpServletRequest.class)
                .enable(false) // 配置是否啟用Swagger扎筒,如果是false莱找,在瀏覽器將無(wú)法訪問(wèn)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }

**4、如何動(dòng)態(tài)配置當(dāng)項(xiàng)目處于test嗜桌、dev環(huán)境時(shí)顯示swagger奥溺,處于prod時(shí)不顯示?
**

@Bean
    public Docket docket(Environment environment) {
        // 設(shè)置要顯示swagger的環(huán)境
        Profiles of = Profiles.of("dev", "test");
        // 判斷當(dāng)前是處于該環(huán)境骨宠,通過(guò) enable() 接收此參數(shù)判斷是否要顯示
        boolean b = environment.acceptsProfiles(of);

        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .ignoredParameterTypes(HttpServletRequest.class)
                .enable(b) // 配置是否啟用Swagger浮定,如果是false,在瀏覽器將無(wú)法訪問(wèn)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }

5诱篷、配置API分組
如果沒(méi)有配置分組壶唤,默認(rèn)是default。通過(guò)groupName()方法即可配置分組:

 //配置分組
    @Bean
    public Docket docketUser(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("用戶(hù)")
                .select().paths(PathSelectors.ant("/user")).build();
    }

    @Bean
    public Docket docketHello(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("你好")
                .select().paths(PathSelectors.ant("/hello")).build();
    }

如下圖所示棕所,我們配置了groupName("user")那么當(dāng)前接口分組信息為user闸盔。


4

6、實(shí)體配置
比如當(dāng)前項(xiàng)目中有這么一個(gè)實(shí)體:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用戶(hù)實(shí)體")
public class User {
    @ApiModelProperty(value = "用戶(hù)id",example = "0")
    private Integer id;
    @ApiModelProperty("用戶(hù)名")
    private String username;
    @ApiModelProperty(value = "用戶(hù)年齡",example = "1")
    private String age;
}

只要這個(gè)實(shí)體在請(qǐng)求接口的返回值上(即使是泛型)琳省,都能映射到實(shí)體項(xiàng)中:

5

注:并不是因?yàn)锧ApiModel這個(gè)注解讓實(shí)體顯示在這里了迎吵,而是只要出現(xiàn)在接口方法的返回值上的實(shí)體都會(huì)顯示在這里,而@ApiModel和@ApiModelProperty這兩個(gè)注解只是為實(shí)體添加注釋的针贬。
@ApiModel為類(lèi)添加注釋
@ApiModelProperty為類(lèi)屬性添加注釋

常用的注解

swagger通過(guò)注解表明該接口文檔會(huì)生成文檔击费,包括接口名,請(qǐng)求方法桦他,參數(shù)蔫巩,返回信息的等等。
@Api修飾整個(gè)類(lèi)快压,描述controller的作用
@ApiOperation:描述一個(gè)類(lèi)的一個(gè)方法圆仔,或者說(shuō)一個(gè)接口
@ApiParam:?jiǎn)蝹€(gè)參數(shù)描述
@ApiModel:當(dāng)接收參數(shù)為對(duì)象時(shí)
@ApiProperty:用對(duì)象接收參數(shù)時(shí),描述對(duì)象的一個(gè)字段
@ApiRespose:HTTP響應(yīng)其中1個(gè)描述
@ApiResponses:HTTP響應(yīng)整體描述
@ApiIgnore:使用該注解忽略這個(gè)API
@ApiError:發(fā)生錯(cuò)誤返回的信息
@ApiImplicitParam:一個(gè)參數(shù)請(qǐng)求
@ApiImplicitParams:多個(gè)請(qǐng)求
詳細(xì)解釋?zhuān)?@Api:用在請(qǐng)求類(lèi)上蔫劣,表示對(duì)類(lèi)的說(shuō)明
tags=“說(shuō)明該類(lèi)的作用坪郭,可以在UI界面上看到的注解”
value=“該參數(shù)沒(méi)什么意義,在UI界面上也看到脉幢,所以不需要配置”
@ApiOperation:用在請(qǐng)求的方法上歪沃,說(shuō)明方法的用途嗦锐,作用
value=“說(shuō)明方法的用途,作用”
notes=“方法的備注說(shuō)明”
@ApiImplicitParams:用在請(qǐng)求的方法上沪曙,表示一組參數(shù)的說(shuō)明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一個(gè)請(qǐng)求參數(shù)的各個(gè)方面
name:參數(shù)名
value:參數(shù)的漢字說(shuō)明
required:參數(shù)放在哪個(gè)地方

header:請(qǐng)求參數(shù)的獲取 @RequestHeader
query:請(qǐng)求參數(shù)的獲取 @RequestParam
path:(用于Restful接口)
body(不常用)
form(不常用)
dataTye:當(dāng)參數(shù)為對(duì)象類(lèi)型時(shí)指定參數(shù)類(lèi)型
@ApiResponses:用在請(qǐng)求的方法上奕污,表示一組響應(yīng)
@ApiResponse:用在@ApiResponses中,一般用于表達(dá)一個(gè)錯(cuò)誤的響應(yīng)信息(實(shí)際上任何相應(yīng)信息都可以)
code:數(shù)字珊蟀,例如400
message:信息菊值,例如“請(qǐng)求參數(shù)沒(méi)填寫(xiě)正確”
response:拋出的異常類(lèi)

@ApiModel:用于響應(yīng)類(lèi)上外驱,表示一個(gè)返回響應(yīng)數(shù)據(jù)的信息(這種一般用在post創(chuàng)建的時(shí)候育灸,使用@RequestBody這樣的場(chǎng)景,請(qǐng)求參數(shù)無(wú)法使用@ApiImplicitParams注解進(jìn)行描述的時(shí)候)
@ApiModelProperty:用在屬性上昵宇,描述響應(yīng)類(lèi)的屬性
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末磅崭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瓦哎,更是在濱河造成了極大的恐慌砸喻,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒋譬,死亡現(xiàn)場(chǎng)離奇詭異割岛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)犯助,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)癣漆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人剂买,你說(shuō)我怎么就攤上這事惠爽。” “怎么了瞬哼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵婚肆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我坐慰,道長(zhǎng)较性,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任结胀,我火速辦了婚禮赞咙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘把跨。我一直安慰自己人弓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布着逐。 她就那樣靜靜地躺著崔赌,像睡著了一般意蛀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上健芭,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天县钥,我揣著相機(jī)與錄音,去河邊找鬼慈迈。 笑死若贮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的痒留。 我是一名探鬼主播谴麦,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伸头!你這毒婦竟也來(lái)了匾效?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恤磷,失蹤者是張志新(化名)和其女友劉穎面哼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扫步,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魔策,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了河胎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯袒。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖仿粹,靈堂內(nèi)的尸體忽然破棺而出搁吓,到底是詐尸還是另有隱情,我是刑警寧澤吭历,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布堕仔,位于F島的核電站,受9級(jí)特大地震影響晌区,放射性物質(zhì)發(fā)生泄漏摩骨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一朗若、第九天 我趴在偏房一處隱蔽的房頂上張望恼五。 院中可真熱鬧,春花似錦哭懈、人聲如沸灾馒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)睬罗。三九已至轨功,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間容达,已是汗流浹背古涧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留花盐,地道東北人羡滑。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像算芯,于是被迫代替她去往敵國(guó)和親柒昏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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

  • 本文屬于原創(chuàng)也祠,轉(zhuǎn)載注明出處昙楚,歡迎關(guān)注微信小程序小白AI博客 微信公眾號(hào)小白AI或者網(wǎng)站 https://xiaob...
    小白AI閱讀 568評(píng)論 0 4
  • 今天技術(shù)總監(jiān)說(shuō):小明近速,我們本次3.0改造诈嘿,使用swagger2.0作為前后端分離的接口規(guī)范,它可以一鍵生成前后端的...
    coder小明閱讀 3,408評(píng)論 4 12
  • 匆忙的云削葱,匆忙的雨匆忙的四季還有奖亚,匆忙的我和你多少次擦肩而過(guò)才換得執(zhí)手相望不分離 都說(shuō),心懷天下呵析砸,天下那么大我要...
    凌洛夕閱讀 329評(píng)論 2 9
  • 學(xué)習(xí)Python的時(shí)候昔字,被Python的各種包管理工具搞的眼花繚亂。通常經(jīng)常會(huì)看到以下幾種:distutils 首繁、...
    aidenliu閱讀 8,125評(píng)論 0 0
  • 面向?qū)ο笫荍ava學(xué)習(xí)中的重點(diǎn)作郭,也是面試找工作的重點(diǎn)考察方向。 1弦疮、概述 面向?qū)ο笤O(shè)計(jì)實(shí)質(zhì)上就是對(duì)現(xiàn)實(shí)世界的對(duì)象進(jìn)...
    小宇java閱讀 927評(píng)論 1 1