Spring Security技術棧學習筆記(七)使用Swagger自動生成API文檔

由於Spring Boot能夠快速開發、便捷部署等特性,相信有很大一部分Spring Boot的用戶會用來構建RESTful API。而我們構建RESTful API的目的通常都是由於多終端的原因,這些終端會共用很多底層業務邏輯,因此我們會抽象出這樣一層來同時服務於多個移動端或者Web前端。本文將介紹RESTful API的重磅好夥伴Swagger2,它可以輕鬆的整合到Spring Boot中,並與Spring MVC程序配合組織出強大RESTful API文檔。它既可以減少我們創建文檔的工作量,同時說明內容又整合入實現代碼中,讓維護文檔和修改代碼整合爲一體,可以讓我們在修改代碼邏輯的同時方便的修改文檔說明。另外Swagger2也提供了強大的頁面測試功能來調試每個RESTful API。此引用來自程序猿DD

Spring Boot中應用中Swagger2構建強大的API文檔十分方便,只需要在項目中添加Swagger2的依賴,然後在Spring Boot的啓動的main方法的類上加上註解@EnableSwagger2就可以完成構建工作。效果圖如下:
這裏寫圖片描述
在圖中可以看出,我自定義的Controller只有FileController,而其他的都是Spring Boot的一些控制器,而這些API文檔往往是我們不需要的,所以,僅僅使用Swagger2的默認方式顯然是不能滿足我們的需求的,所以,我們需要自定義Swagger文檔。

添加依賴

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

配置Swagger

我們寫一個Swagger的配置類,添加上@Configuration註解方便被Spring Boot配置,添加@EnableSwagger2註解啓動Swagger文檔構建能力。需要注意的是,一般配置類可以放在Spring Boot啓動類的同一個包裏,如果沒有放,那麼請在Spring Boot的啓動類上添加包掃描註解@ComponentScan(basePackages = {"com.lemon.security"}),然後配置類可以放在任何的這個包的子包下面。

package com.lemon.security.web.config;

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.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author lemon
 * @date 2018/4/3 下午1:01
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestfulApiDocs() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.lemon.security.web.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("自定義RESTful API文檔")
                .description("更多內容請關注CSDN博客:https://blog.csdn.net/Lammonpeter")
                .termsOfServiceUrl("https://blog.csdn.net/Lammonpeter")
                .contact(new Contact("Lemon", "https://blog.csdn.net/Lammonpeter", "[email protected]"))
                .version("1.0.0")
                .build();
    }
}

對上面的代碼有如下解釋:
通過createRestfulApiDocs方法創建DocketBean之後,apiInfo()用來創建該API的基本信息(這些基本信息會展現在文檔頁面中)。select()函數返回一個ApiSelectorBuilder實例用來控制哪些接口暴露給Swagger來展現,本例採用指定掃描的包路徑來定義,Swagger會掃描該包下所有Controller定義的API,併產生文檔內容(除了被@ApiIgnore指定的請求)。

添加文檔內容

在完成了上述配置後,其實已經可以生產文檔內容,但是這樣的文檔主要針對請求本身,而描述主要來源於函數等命名產生,對用戶並不友好,我們通常需要自己增加一些說明來豐富文檔內容。如下所示,我們通過@ApiOperation註解來給API方法增加說明,通過@ApiImplicitParams@ApiImplicitParam註解來給參數增加說明,通過@ApiModelProperty註解來給實體類的屬性增加說明。

  • Controller添加文檔說明:
package com.lemon.security.web.controller;

import cn.hutool.core.io.IoUtil;
import com.lemon.security.web.dto.FileInfo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * @author lemon
 * @date 2018/4/2 下午2:19
 */
@RestController
@RequestMapping("/file")
public class FileController {

    private static String folder = "/Users/lemon/IdeaProjects/spring-security/lemon-security-demo";

    @PostMapping
    @ApiOperation(value = "文件上傳接口", notes = "訪問此接口可以實現文件上傳")
    @ApiImplicitParam(name = "file", value = "使用MultipartFile的實例對象來接收文件數據", required = true, dataTypeClass = MultipartFile.class)
    public FileInfo upload(@RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("上傳文件的表單name值爲:" + file.getName());
        System.out.println("文件路徑爲:" + file.getOriginalFilename());
        System.out.println("文件大小爲:" + file.getSize());
        File localFile = new File(folder, System.currentTimeMillis() + ".txt");
        // 執行上傳操作
        file.transferTo(localFile);
        return new FileInfo(localFile.getAbsolutePath());
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "文件下載接口", notes = "訪問此接口並提供文件ID即可下載文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文件ID", required = true, dataTypeClass = String.class),
            @ApiImplicitParam(name = "request", value = "HttpServletRequest實例對象,自動注入,無需傳遞", required = true, dataTypeClass = HttpServletRequest.class),
            @ApiImplicitParam(name = "response", value = "HttpServletResponse實例對象,自動注入,無需傳遞", required = true, dataTypeClass = HttpServletResponse.class)
    })
    public void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
        System.out.println(folder);
        try (
                // 這是JDK7的特性,關於流的操作,可以寫在try後面的圓括號裏,這樣就無需手動關閉流
                InputStream inputStream = new FileInputStream(new File(folder, id + ".txt"));
                OutputStream outputStream = response.getOutputStream()
        ) {
            // 設置下載的文件類型
            response.setContentType("application/x-download");
            // 設置下載後的文件名
            response.setHeader("Content-Disposition", "attachment;filename=test.txt");
            IoUtil.copy(inputStream, outputStream);
            // 刷新輸出流
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

其中,
@ApiOperation註解的value屬性一般都是簡單描述API的功能,notes屬性詳細描述API的功能;
@ApiImplicitParams用來描述一個方法的多個參數的註解;
@ApiImplicitParam用來表述單個參數,name屬性來描述參數的名稱,value用來描述參數的意思,required表示參數是否是必需值,dataTypeClass或者dataType指定了數據的類型。
這裏僅僅是對註解進行說明,而代碼本身來自上一節內容,即《Spring Security技術棧開發企業級認證與授權(六)使用REST方式處理文件服務》。

  • 給實體類添加文檔說明:
package com.lemon.security.web.dto;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author lemon
 * @date 2018/4/2 下午2:24
 */
@Data
public class FileInfo {

    @ApiModelProperty(value = "文件上傳後的文件路徑")
    private String path;

    public FileInfo(String path) {
        this.path = path;
    }
}

其中,@ApiModelProperty用來描述參數的意義。

配置完成以後,運行Spring Boot應用,在地址欄訪問http://localhost:8080/swagger-ui.html就可以進入自定義的Swagger文檔界面,效果圖如下:
這裏寫圖片描述
這裏寫圖片描述

API文檔訪問與調試

在上圖請求的頁面中,Swagger除了查看接口功能外,還提供了調試測試功能,點擊“Try it out!”按鈕,即可完成了一次請求調用!此時,你也可以通過幾個POST請求來驗證之前的POST請求是否正確。相比爲這些接口編寫文檔的工作,我們增加的配置內容是非常少而且精簡的,對於原有代碼的侵入也在忍受範圍之內。因此,在構建RESTful API的同時,加入Swagger來對API文檔進行管理,是個不錯的選擇。

Spring Security技術棧開發企業級認證與授權系列文章列表:

Spring Security技術棧學習筆記(一)環境搭建
Spring Security技術棧學習筆記(二)RESTful API詳解
Spring Security技術棧學習筆記(三)表單校驗以及自定義校驗註解開發
Spring Security技術棧學習筆記(四)RESTful API服務異常處理
Spring Security技術棧學習筆記(五)使用Filter、Interceptor和AOP攔截REST服務
Spring Security技術棧學習筆記(六)使用REST方式處理文件服務
Spring Security技術棧學習筆記(七)使用Swagger自動生成API文檔
Spring Security技術棧學習筆記(八)Spring Security的基本運行原理與個性化登錄實現
Spring Security技術棧學習筆記(九)開發圖形驗證碼接口
Spring Security技術棧學習筆記(十)開發記住我功能
Spring Security技術棧學習筆記(十一)開發短信驗證碼登錄
Spring Security技術棧學習筆記(十二)將短信驗證碼驗證方式集成到Spring Security
Spring Security技術棧學習筆記(十三)Spring Social集成第三方登錄驗證開發流程介紹
Spring Security技術棧學習筆記(十四)使用Spring Social集成QQ登錄驗證方式
Spring Security技術棧學習筆記(十五)解決Spring Social集成QQ登錄後的註冊問題
Spring Security技術棧學習筆記(十六)使用Spring Social集成微信登錄驗證方式

示例代碼下載地址:

項目已經上傳到碼雲,歡迎下載,內容所在文件夾爲chapter007

更多幹貨分享,歡迎關注我的微信公衆號:爪哇論劍(微信號:itlemon)
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章