Spring Boot 使用swagger2

swagger2可以減少我們的編寫文檔工作露懒,尤其現(xiàn)在是前后端分離。后端寫好接口之后還需要寫API使用文檔給客戶端人員砂心,尤其是在接口變更之后懈词,文檔往往就得不到及時(shí)的更新甚至是遺忘,導(dǎo)致文檔最終變得不可信辩诞。這個(gè)框架可以幫助解決此類問題坎弯,減少后端人員的工作量,同時(shí)還能保持維護(hù)文檔的地方只有一處。

這個(gè)框架也只是幫助減少上述問題抠忘,如果只是修改了代碼撩炊,而沒有更新相應(yīng)的描述信息等,也是會(huì)存在上述問題的崎脉。

一拧咳、準(zhǔn)備工作

添加依賴,在pom.xml文件添加如下的依賴:

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

二囚灼、配置swagger2

在Application.java平級(jí)的包下骆膝,新建一個(gè)Swagger2的類,內(nèi)容如下灶体,其中需要注意的是createRestApi方法下的包名為自己項(xiàng)目中的包名阅签,一般為控制器所在的包。

**
 * Swagger2配置類
 * 1)在集成spring boot時(shí)蝎抽,放在與Application.java同級(jí)目錄下
 * 2)@Configuration注解的作用是讓spring 來加載該類的配置
 * 3)@EnableSwagger2 是用來啟用swagger2
 *
 * @author xiaozhao
 * @date 2018/10/19下午3:14
 */
@Configuration
@EnableSwagger2
public class Swagger2 {

    /**
     * 指定掃描包的路徑來指定要?jiǎng)?chuàng)建API的目錄政钟,一般是控制器這個(gè)包
     *
     * @return
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xiaozhao.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 設(shè)置API的基本信息
     *
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("我的公司")
                .description("后端接口說明文檔")
                .termsOfServiceUrl("http://www.reibang.com")
                .version("1.0")
                .build();
    }
}
image.png

三、swagger2常用注解說明

  • @Api()
    value: 不能顯示到UI上
    tags:一個(gè)字符串?dāng)?shù)組织中,說明整個(gè)類的作用锥涕,會(huì)顯示在UI上。此處發(fā)現(xiàn)一個(gè)問題狭吼,就是為中文時(shí)层坠,導(dǎo)致接口在UI上不能展開。

修飾在類上刁笙,描述一個(gè)類的作用破花。例如:

@Api(value = "歡迎", tags = {"用戶操作接口說明"})
public class HelloController {
}
  • @ApiOperation()
    value:說明方法的用途、作用
    notes:方法的備注說明
    修飾方法疲吸,說明方法的作用座每,例如:
    @GetMapping("/hi")
    @ApiOperation(value = "問候語(yǔ)", notes = "這是一個(gè)問候", httpMethod = "GET")
    public String hello() {
        return "Hell World";
    }
  • @ApiImplicitParams
    是一個(gè)@ApiImplicitParam的數(shù)組,用在請(qǐng)求的方法上摘悴,包含一組參數(shù)說明

  • @ApiImplicitParam
    name:參數(shù)名
    value:參數(shù)的漢字說明峭梳,描述信息
    required:是否必需
    dataType:參數(shù)類型,默認(rèn)String蹂喻,其它值dataType="Integer" 或dataType="User" 或 ......
    defaultValue:參數(shù)的默認(rèn)值
    paramType:參數(shù)放在哪個(gè)地方

            header --> 請(qǐng)求參數(shù)的獲却型帧:@RequestHeader
            query --> 請(qǐng)求參數(shù)的獲取:@RequestParam
            path(用于restful接口)--> 請(qǐng)求參數(shù)的獲瓤谒摹:@PathVariable
            body(不常用)
            form(不常用)  

用來說明方法的參數(shù)孵运,例如:

    @RequestMapping(value = "/update/{id}", method = RequestMethod.PUT)
    @ApiOperation(value = "更新信息", notes = "根據(jù)url的id來指定更新用戶信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用戶ID", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "user", value = "用戶實(shí)體", required = true, dataType = "User")
    })
    public String putUser(@PathVariable Long id, @RequestBody User user) {
        System.out.println(id);
        System.out.println(user.getId());
        System.out.println(user.getName());
        return "修改成功";
    }
  • @ApiParam
    name:參數(shù)名
    value:參數(shù)的漢字說明,描述信息
    required:是否必需
    用于方法蔓彩、參數(shù)的說明治笨,例如:
    @ApiOperation("更改用戶信息")
    @PostMapping("/updateUserInfo")
    public int test(@RequestBody @ApiParam(name = "用戶對(duì)象", value = "傳入json格式", required = true) User user) {
        return 1;
    }
  • @ApiResponses
    是一個(gè)@ApiResponse的數(shù)組驳概,用于請(qǐng)求的方法上,表示一組響應(yīng)

  • @ApiResponse()
    code:標(biāo)準(zhǔn)的http響應(yīng)碼旷赖,例如404顺又,500,502等
    message:錯(cuò)誤信息杠愧,例如“參數(shù)錯(cuò)誤”
    response:拋出異常的類
    修飾方法待榔,表達(dá)一個(gè)錯(cuò)誤的響應(yīng),例如:

    @GetMapping("/hi")
    @ApiOperation(value = "問候語(yǔ)", notes = "這是一個(gè)問候", httpMethod = "GET")
    @ApiResponses({
            @ApiResponse(code = 400, message = "請(qǐng)求參數(shù)沒填好"),
            @ApiResponse(code = 404, message = "請(qǐng)求路徑?jīng)]有或頁(yè)面跳轉(zhuǎn)路徑不對(duì)")
    })
    public String hello() {
        return "Hell World";
    }
  • @ApiModel()
    value:類名
    description:描述

一般用于參數(shù)為一個(gè)實(shí)體類時(shí)流济,說明這個(gè)類的各項(xiàng)屬性的含義锐锣。只能修飾在類上,需要配合@ApiProperty一起使用绳瘟,例如:

@ApiModel
public class User implements Serializable {
    private static final long serialVersionUID = -1084928517040754103L;
}
  • @ApiModelProperty()
    name:屬性名稱
    value:描述
    dataType:屬性的數(shù)據(jù)類型
    required:是否必填
    example:舉例說明
    hidden:在文檔上是否不可見

修飾實(shí)體類的屬性雕憔,例如:

    @ApiModelProperty(value = "用戶id", name = "id", required = false)
    private Integer id;

    @ApiModelProperty(value = "用戶名稱", name = "name", required = true,example = "張颯")
    private String name;


   //省略  getter and setter 
image.png

*@ApiIgnore
可以修飾類或者非法,然后在文檔中不再顯示

四糖声、項(xiàng)目中使用

用戶實(shí)體類

/**
 * 用戶實(shí)體類
 *
 * @author xiaozhao
 * @date 2018/10/19下午3:35
 */
@ApiModel
public class User implements Serializable {

    private static final long serialVersionUID = -1084928517040754103L;
    @ApiModelProperty(value = "用戶id", name = "id", required = false)
    private Integer id;

    @ApiModelProperty(value = "用戶名稱", name = "name", required = true, example = "張颯")
    private String name;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

控制器

/**
 * swagger2 示例
 *
 * @author xiaozhao
 * @date 2018/10/19下午3:17
 */
@RestController
@RequestMapping("/api")
@Api(value = "Welcome", tags = {"User Guide"})
public class HelloController {

    /**
     * 無參數(shù)斤彼,只有說明
     *
     * @return 返回字符串
     */
    @GetMapping("/hi")
    @ApiOperation(value = "問候語(yǔ)", notes = "這是一個(gè)問候", httpMethod = "GET")
    @ApiResponses({
            @ApiResponse(code = 400, message = "請(qǐng)求參數(shù)沒填好"),
            @ApiResponse(code = 404, message = "請(qǐng)求路徑?jīng)]有或頁(yè)面跳轉(zhuǎn)路徑不對(duì)")
    })
    public String hello() {
        return "Hell World";
    }

    /**
     * 無參數(shù)
     *
     * @return 返回一個(gè)對(duì)象
     */
    @GetMapping("/list")
    @ApiOperation(value = "列表", notes = "獲取用戶列表", httpMethod = "GET")
    public HttpResult list() {
        HttpResult httpResult = new HttpResult();
        httpResult.setCode(0);
        httpResult.setMsg("");
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setId(1);
        user.setName("James");
        list.add(user);
        httpResult.setData(list);
        return httpResult;
    }


    /**
     * 有一個(gè)簡(jiǎn)單類型的參數(shù),rest風(fēng)格
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/find/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "查找用戶", notes = "查找某個(gè)用戶的詳細(xì)信息")
    @ApiImplicitParam(name = "id", value = "用戶唯一標(biāo)識(shí)", required = true, dataType = "Long", paramType = "path")
    public User getBook(@PathVariable Long id) {
        System.out.println(id);
        User user = new User();
        user.setId(1);
        user.setName("庫(kù)里");
        return user;
    }

    /**
     * 有一個(gè)引用類型的參數(shù)
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加用戶", notes = "添加一個(gè)新的用戶")
    @ApiImplicitParam(name = "user", value = "用戶詳細(xì)實(shí)體", required = true, dataType = "User")
    public String postBook(@RequestBody User user) {
        System.out.println(user);
        return "添加用戶成功";
    }


    /**
     * 有一個(gè)簡(jiǎn)單類型的參數(shù)和一個(gè)引用類型的參數(shù)
     *
     * @param id
     * @param user
     * @return
     */
    @RequestMapping(value = "/update/{id}", method = RequestMethod.PUT)
    @ApiOperation(value = "更新信息", notes = "根據(jù)url的id來指定更新用戶信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用戶ID", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "user", value = "用戶實(shí)體", required = true, dataType = "User")
    })
    public String putUser(@PathVariable Long id, @RequestBody User user) {
        System.out.println(id);
        System.out.println(user.getId());
        System.out.println(user.getName());
        return "修改成功";
    }

    /**
     * 有一個(gè)Long的參數(shù)
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/del_user/{id}", method = RequestMethod.DELETE)
    @ApiOperation(value = "刪除用戶", notes = "根據(jù)id來刪除指定用戶")
    @ApiImplicitParam(name = "id", value = "用戶ID", required = true, dataType = "Long", paramType = "path")
    public String deleteUser(@PathVariable Long id) {
        System.out.println("刪除用戶:" + id);
        return "success";
    }

    /**
     * 使用該注解忽略這個(gè)API
     *
     * @return
     */
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ApiIgnore
    public String jsonTest() {
        return " hi you!";
    }


    @ApiOperation("更改用戶信息")
    @PostMapping("/updateUserInfo")
    public int test(@RequestBody @ApiParam(name = "用戶對(duì)象", value = "傳入json格式", required = true) User user) {
        return 1;
    }
}

最后運(yùn)行項(xiàng)目蘸泻,然后在瀏覽器中打開 http://localhost:8080/swagger-ui.html

看到如下界面

image.png

image.png

完整代碼

https://github.com/xiaozhaowen/spring-boot-in-action/tree/master/springboot-swagger2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琉苇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子悦施,更是在濱河造成了極大的恐慌并扇,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡诞,死亡現(xiàn)場(chǎng)離奇詭異穷蛹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)昼汗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門肴熏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人顷窒,你說我怎么就攤上這事蛙吏。” “怎么了鞋吉?”我有些...
    開封第一講書人閱讀 157,812評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵出刷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我坯辩,道長(zhǎng),這世上最難降的妖魔是什么崩侠? 我笑而不...
    開封第一講書人閱讀 56,607評(píng)論 1 284
  • 正文 為了忘掉前任漆魔,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘改抡。我一直安慰自己矢炼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評(píng)論 6 386
  • 文/花漫 我一把揭開白布阿纤。 她就那樣靜靜地躺著句灌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欠拾。 梳的紋絲不亂的頭發(fā)上胰锌,一...
    開封第一講書人閱讀 49,919評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音藐窄,去河邊找鬼资昧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛荆忍,可吹牛的內(nèi)容都是我干的格带。 我是一名探鬼主播,決...
    沈念sama閱讀 39,071評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼刹枉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼叽唱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起微宝,我...
    開封第一講書人閱讀 37,802評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤棺亭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后芥吟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侦铜,經(jīng)...
    沈念sama閱讀 44,256評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評(píng)論 2 327
  • 正文 我和宋清朗相戀三年钟鸵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钉稍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,712評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棺耍,死狀恐怖贡未,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蒙袍,我是刑警寧澤俊卤,帶...
    沈念sama閱讀 34,389評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站害幅,受9級(jí)特大地震影響消恍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜以现,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評(píng)論 3 316
  • 文/蒙蒙 一狠怨、第九天 我趴在偏房一處隱蔽的房頂上張望约啊。 院中可真熱鬧,春花似錦佣赖、人聲如沸恰矩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)外傅。三九已至,卻和暖如春俩檬,著一層夾襖步出監(jiān)牢的瞬間萎胰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工豆胸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奥洼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,473評(píng)論 2 360
  • 正文 我出身青樓晚胡,卻偏偏與公主長(zhǎng)得像灵奖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子估盘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評(píng)論 2 350