1. 程式人生 > >基於swagger做介面管理

基於swagger做介面管理

文章轉載地址:http://javatech.wang/index.PHP/archives/74/

筆者目前正在搭建一套API服務框架,考慮到客戶端能夠更方便的呼叫API服務(這裡說的更方便是指避免不厭其煩地解說各介面需要的引數和返回結果),於 是決心為每個介面生成詳細的說明文件。網上搜索了一下,發現了Swagger這個東西,感覺不錯,介面也比javadoc生成的頁面要美觀,而且網上關於 Swagger和springmvc整合的文章不少(遺憾的是大多雷同且不完整)。本文詳細介紹Swagger和SpringMVC的整合過程,重點是彌 補現有文章的遺漏之處(很關鍵的哦!)。讓我們一起來學習如何使用Swagger來生成介面文件吧!

  既然是整合Swagger,那麼前提是你已經使用SpringMVC搭建了一套介面服務, 無論繁簡,只要可用就行。關於介面文件生成工具,大家在網上搜索的時候,可能會發現另外一個工具:springfox。網上關於springfox和 spring整合的文章也非常多的呀。那springfox和swagger是什麼關係呢?引用springfox官方的語錄:

Springfox has evolved from a project originally created by Marty Pitt and was named swagger-springmvc.

  這段英文很簡單,不懂的讀者對照線上詞典也可以翻譯出來,加油!言歸正傳,先簡單介紹下專案環境:

  • JDK1.7
  • Spring 3.2.2
  • swagger-springmvc 1.0.2 (最新版本)

一、依賴管理

  在整合之前,需要把所有使用到的依賴包全部引入。網上很多文章只是簡單告訴讀者引入swagger-springmvc-1.0.2.jar包,但是隨後你發現這遠遠不夠,還需要很多包,如下所示:

<!-- swagger-springmvc -->
    <dependency>
        <groupId>com.mangofactory</groupId>
        <artifactId>swagger-springmvc</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.mangofactory</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>1.3.11</version>
    </dependency>
    <!-- swagger-springmvc dependencies -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>15.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.4.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.4.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.4.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml</groupId>
        <artifactId>classmate</artifactId>
        <version>1.1.0</version>
    </dependency>

  以上是比較完整的依賴列表,本文搭建的專案可以正常執行。讀者可能會有疑問,maven管理的依賴包不是具有傳遞性嗎?是的,是有傳遞性,但是傳遞性是根據<scope>來界定的。開啟swagger-springmvc依賴包的pom檔案可以發現,其很多依賴包的scope值為compile或者provider,不會根據傳遞性自動引入。

二、Swagger配置

  Swagger的配置實際上就是自定義一個Config類,通過Java編碼的方式實現配置。程式碼如下:

import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.models.dto.ApiInfo;
import com.mangofactory.swagger.plugin.EnableSwagger;
import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by xiaohui on 2016/1/14.
 */
@Configuration
@EnableSwagger
public class SwaggerConfig {

    private SpringSwaggerConfig springSwaggerConfig;

    /**
     * Required to autowire SpringSwaggerConfig
     */
    @Autowired
    public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig)
    {
        this.springSwaggerConfig = springSwaggerConfig;
    }

    /**
     * Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc
     * framework - allowing for multiple swagger groups i.e. same code base
     * multiple swagger resource listings.
     */
    @Bean
    public SwaggerSpringMvcPlugin customImplementation()
    {
        return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
                .apiInfo(apiInfo())
                .includePatterns(".*?");
    }

    private ApiInfo apiInfo()
    {
        ApiInfo apiInfo = new ApiInfo(
                "My Apps API Title",
                "My Apps API Description",
                "My Apps API terms of service",
                "My Apps API Contact Email",
                "My Apps API Licence Type",
                "My Apps API License URL");
        return apiInfo;
    }
}

  上面這段程式碼是從網路上找到的,你也肯定找到了,對吧!但是,你會發現一個問題:SpringSwaggerConfig無法注入。這是為什麼呢?其實很簡單,因為spring容器裡沒有SpringSwaggerConfig型別的物件。解決辦法:在springmvc的配置檔案中加入以下配置即可。

<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />

  到目前為止,我們已經完成了對所有介面方法的掃描解析功能,那解析得到什麼內容呢?這需要我們自定義,自定義操作的物件就是介面方法。先看段程式碼:

/**
 * 根據使用者名稱獲取使用者物件
 * @param name
 * @return
 */
@RequestMapping(value="/name/{name}", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "根據使用者名稱獲取使用者物件", httpMethod = "GET", response = ApiResult.class, notes = "根據使用者名稱獲取使用者物件")
public ApiResult getUserByName(@ApiParam(required = true, name = "name", value = "使用者名稱") @PathVariable String name) throws Exception{
    UcUser ucUser = ucUserManager.getUserByName(name);

    if(ucUser != null) {
        ApiResult<UcUser> result = new ApiResult<UcUser>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setData(ucUser);
        return result;
    } else {
        throw new BusinessException("根據{name=" + name + "}獲取不到UcUser物件");
    }
}

  上述程式碼是Controller中的一個方法,@ApiOperation註解對這個方法進行了說明,@ApiParam註解對方法引數進行了說明。關於這兩個註解的使用,可以參看原始碼。這樣子,Swagger就可以掃描介面方法,得到我們自定義的介面說明內容。

三、Swagger-UI配置

  Swagger掃描解析得到的是一個json文件,對於使用者不太友好。下面介紹swagger-ui,它能夠友好的展示解析得到的介面說明內容。

  從https://github.com/swagger-api/swagger-ui 獲取其所有的 dist 目錄下東西放到需要整合的專案裡,本文放入 src/main/webapp/WEB-INF/swagger/ 目錄下。

  修改swagger/index.html檔案,預設是從連線http://petstore.swagger.io/v2 /swagger.json獲取 API 的 JSON,這裡需要將url值修改為http://{ip}:{port}/{projectName}/api-docs的形式,{}中的值根據自身情 況填寫。比如我的url值為:http://localhost:8083/arrow-api/api-docs

  因為swagger-ui專案都是靜態資源,restful形式的攔截方法會將靜態資源進行攔截處理,所以在springmvc配置檔案中需要配置對靜態檔案的處理方式。

//所有swagger目錄的訪問,直接訪問location指定的目錄
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>

  OK!大功告成,開啟瀏覽器直接訪問swagger目錄下的index.html檔案,即可看到介面文件說明了。注意訪問地址哦!看下圖: