1. 程式人生 > >在Spring中使用Springfox和swagger生成restful風格的API文件

在Spring中使用Springfox和swagger生成restful風格的API文件

發現一位博主寫的特別棒 強烈推薦參考他的:大牛的網址

由於Spring Boot能夠快速開發、便捷部署等特性,相信有很大一部分Spring Boot的使用者會用來構建RESTful API。而我們構建RESTful API的目的通常都是由於多終端的原因,這些終端會共用很多底層業務邏輯,因此我們會抽象出這樣一層來同時服務於多個移動端或者Web前端。

這樣一來,我們的RESTful API就有可能要面對多個開發人員或多個開發團隊:IOS開發、Android開發或是Web開發等。為了減少與其他團隊平時開發期間的頻繁溝通成本,傳統做法我們會建立一份RESTful API文件來記錄所有介面細節,然而這樣的做法有以下幾個問題:
由於介面眾多,並且細節複雜(需要考慮不同的HTTP請求型別、HTTP頭部資訊、HTTP請求內容等),高質量地建立這份文件本身就是件非常吃力的事,下游的抱怨聲不絕於耳。
隨著時間推移,不斷修改介面實現的時候都必須同步修改介面文件,而文件與程式碼又處於兩個不同的媒介,除非有嚴格的管理機制,不然很容易導致不一致現象。

為了解決上面這樣的問題,本文將介紹RESTful API的重磅好夥伴Swagger2,它可以輕鬆的整合到Spring Boot中,並與Spring MVC程式配合組織出強大RESTful API文件。它既可以減少我們建立文件的工作量,同時說明內容又整合入實現程式碼中,讓維護文件和修改程式碼整合為一體,可以讓我們在修改程式碼邏輯的同時方便的修改文件說明。另外Swagger2也提供了強大的頁面測試功能來除錯每個RESTful API。

springfox是通過註解的形式自動生成API文件的,利用它,可以很方便的學些restful API;swagger主要使用者展示springfox生成的API文件,而且還提供測試介面,自動顯示json格式的響應,大大方便了後臺開發人員和前端的溝通與聯調成本。

swagger

swagger是一個規範的完整的框架,使用者生成、描述、呼叫和視覺化RESTful風格的Web服務。總體的目標是使客戶端和檔案系統作為伺服器以同樣的速度來更新。檔案的方法,引數和模型緊密繼承到伺服器端的diamante,允許API來始終保持同步。Swagger讓部署管理和使用功能強大的API從未如此簡單

springfox-swagger

swagger的功能非常強大,spring這個大神就開始試圖想把swagger繼承到自己的專案中,就有了後來的spring-swagger,再後來又演變成了springfox。雖然是通過plug的方式把swagger整合進來,但是它本身對api的生成,主要還是依靠swagger實現的。

SpringFox的大致原理

springfox的大致原理就是,在專案啟動的過程中,spring上下文的初始化的過程,框架自動根據配置家在一些swagger相關的bean到當前的上下文,並且自動掃描系統中可能需要生成的api文件的那些類,並生成響應的資訊快取起來。一般的都會掃描控制層Controller類,根據這些Controller類中的功能方法自動生成API介面文件。

使用步驟:(使用的軟體:IDEA,語言:kotlin)

1.在pom.xml中新增maven依賴

        <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>
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
            <version>1.1.2.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-staticdocs</artifactId>
            <version>2.6.1</version>
        </dependency>

2.新增Swagger2的配置檔案:configuration

需要特別注意的是swagger scan base package,這是掃描註解的配置,即你的介面位置。

    import org.springframework.context.annotation.Bean
    import org.springframework.context.annotation.Configuration
    import org.springframework.http.ResponseEntity
    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.swagger.web.UiConfiguration
    import springfox.documentation.swagger2.annotations.EnableSwagger2

    @Configuration
    @EnableSwagger2
    class Swagger2Config {

    @Bean
    fun restfulApi(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
                .genericModelSubstitutes(ResponseEntity::class.java)
                .useDefaultResponseMessages(true)
                .forCodeGeneration(true)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.company.service.web"))
                .paths(PathSelectors.any())
                .build()
                .pathMapping("/")
                .apiInfo(apiInfo())
    }

    private fun apiInfo(): ApiInfo {
        return ApiInfoBuilder()
                .title("API文件")
                .description(this.description)
                .termsOfServiceUrl("http://路徑.com")
                .contact(Contact("name", "http://name.com", "[email protected]"))
                .version("1.0.0")
                .build()
    }

    private val description = "Api 文件規範."
}

這裡的@Configuration註解,讓spring載入配置,@EnableSwagger2啟用Swagger2
再通過createRestApi函式建立Docket的Bean之後,apiInfo()用來建立該Api的基本資訊(這些基本資訊會展現在文件頁面中)。select()函式返回一個ApiSelectorBuilder例項用來控制哪些介面暴露給Swagger來展現,本例採用指定掃描的包路徑來定義,Swagger會掃描該包下所有Controller定義的API,併產生文件內容(除了被@ApiIgnore指定的請求)。

3.在API上做一些宣告:在Controller類中新增相關的swagger註解。但是有一個要求,這個Controller類一定要讓上一步配置類的@ComponentScan掃描到;

@RestController
@Api(value = "User", description = "the chapter of user")
@RequestMapping("/users", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
class UserController {

    @Resource private lateinit var userService: IUserService
    @Resource private lateinit var orgResponse: OrgResponse
    @Resource private lateinit var iDGenerator: IDGenerator

    @ApiOperation(value = "createUser", notes = "建立一個使用者")
    @ApiImplicitParam(name = "zy", value = "使用者名稱", paramType = "path", required = true, dataType = "String")
    @PostMapping(consumes = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    fun create(@Valid @RequestBody user: SysUser,@PathVariable userName:String): ResponseEntity<Any> {
       return null
    }
}

使用Spring Rest Docs 可以通過測試生成響應的Asciidoc片段,mockmvc類是屬於dosc的。

@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest
class UserControllerTest {

    @Resource private lateinit var context: WebApplicationContext
    private lateinit var mockMvc: MockMvc

    @Rule @JvmField var restDocumentation = JUnitRestDocumentation("target/asciidoc/snippets")

    @Before
    fun setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .apply<DefaultMockMvcBuilder>(documentationConfiguration(this.restDocumentation))
                .build()
    }

    @After
    fun tearDown() {
    }

    @Test
    fun create() {
        val json = """
                {
                    "userName": "zy",
                    "email": "[email protected]",
                    "password": "zy2017"
                }
             """
        val request = post("/users")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(json)
                .accept(MediaType.APPLICATION_JSON_UTF8)

        this.mockMvc.perform(request)
                .andExpect(status().isCreated)
                .andDo(print())
                //spring Rest Docs生成Asciidoc片段
                .andDo(document("createUser", preprocessResponse(prettyPrint())))

    }

生成html和pdf

1.首先在index中引入整個asciidoc的三行程式碼:

include::{generated}/overview.adoc[]
include::{generated}/paths.adoc[]
include::{generated}/definitions.adoc[]

2.在pom.xml檔案中新增asciidoctor的外掛

            <!--asciidoc-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*Documentation.java</include>
                    </includes>
                </configuration>
            </plugin>
            <!-- Run the generated asciidoc through Asciidoctor to generate
                 other documentation types, such as PDFs or HTML5 -->
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>
                <!-- Include Asciidoctor PDF for pdf generation -->
                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>1.5.0-alpha.11</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>1.7.21</version>
                    </dependency>
                </dependencies>
                <!-- Configure generic document generation settings -->
                <configuration>
                    <sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>
                    <sourceDocumentName>index.adoc</sourceDocumentName>
                    <attributes>
                        <doctype>book</doctype>
                        <toc>left</toc>
                        <toclevels>3</toclevels>
                        <numbered/>
                        <hardbreaks/>
                        <sectlinks/>
                        <sectanchors/>
                        <generated>${generated.asciidoc.directory}</generated>
                    </attributes>
                </configuration>
                <!-- Since each execution can only handle one backend, run
                     separate executions for each desired output type -->
                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
                        </configuration>
                    </execution>

                    <execution>
                        <id>output-pdf</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory>
                        </configuration>
                    </execution>

                </executions>
            </plugin>

3.現在執行SwaggerTest,整合片段成html檔案

import io.github.robwin.markup.builder.MarkupLanguage
import io.github.robwin.swagger2markup.GroupBy
import io.github.robwin.swagger2markup.Swagger2MarkupConverter
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.context.WebApplicationContext
import springfox.documentation.staticdocs.Swagger2MarkupResultHandler.outputDirectory
import springfox.documentation.staticdocs.SwaggerResultHandler
import javax.annotation.Resource


/**
 * Description
 * @date 2017-04-17
 */
@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest
//@AutoConfigureRestDocs(outputDir = "target/asciidoc/snippets")
class Swagger2MarkupTest {

    @Resource private val context: WebApplicationContext? = null
    private lateinit var mockMvc: MockMvc

    @Before
    fun setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context!!).build()
    }

    private val snippetDir = "target/asciidoc/snippets"
    private val outputDir = "target/asciidoc/generated"

    @Test
    @Throws(Exception::class)
    fun convertToAsciiDoc() {

        // 得到swagger.json,寫入outputDir目錄中
        this.mockMvc.perform(get("/v2/api-docs")
                .accept(MediaType.APPLICATION_JSON))
                .andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
                .andExpect(status().isOk)
                .andReturn()

        // 讀取上一步生成的swagger.json轉成asciiDoc,寫入到outputDir
        // 這個outputDir必須和外掛裡面<generated></generated>標籤配置一致
        Swagger2MarkupConverter.from(outputDir + "/swagger.json")
                .withPathsGroupedBy(GroupBy.TAGS)// 按tag排序
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
                .withExamples(snippetDir) //插入測試生成的片段
                .build()
                .intoFolder(outputDir) // 輸出
    }

    @Test
    @Throws(Exception::class)
    fun convert2AsciiDoc() {
        this.mockMvc.perform(get("/v2/api-docs")
                .accept(MediaType.APPLICATION_JSON))
                .andDo(outputDirectory(outputDir)
                        .withPathsGroupedBy(GroupBy.TAGS)
                        .withExamples(snippetDir)
                        .build())
                .andExpect(status().isOk)
    }

}

執行測試和maven之後得到下面這樣的:
這裡寫圖片描述

生成的api.xml將是這樣的:
這裡寫圖片描述

常用的註解:
* @Api:將Controller標記為Swagger文件資源。
* @ApiOperation:描述一個類的一個方法,或者說一個介面
* @ApiImplicitParams :多個引數描述
* @ApiImplicitParam:單個引數描述
* @ApiModel:用物件來接收引數
* @ApiModelProperty:用物件接收引數時,描述物件的一個欄位
其它
* @ApiResponse:HTTP響應其中1個描述
* @ApiResponses:HTTP響應整體描述

詳細的引數說明:
*@Api(value = “api的name”,notes = “描述”)
*@ApiOperation(value = “操作的名稱”, notes = “對操作的描述”)
*@ ApiResponse(code = 返回的數字碼, message = “對應的訊息內容”, response = 返回值類)
*@ApiImplicitParam(name = “引數名稱”, value = “引數的描述,或者值”, paramType = “引數位置”, required = true(boolean值,是否必須提供), dataType = “引數的資料型別”)
(((其中,位置引數型別paramType分為以下幾種,是根據它被什麼註解而對應的型別,這裡的型別一定要和方法中的引數註解要相同,要不然獲取不到值。下面是簡介:
@RequestHeader—–paramType = “header”
@RequestParam—–paramType = “query”
@PathVariable—–paramType = “path”
@RequestBody—–paramType = “body”

4.設定訪問API doc的路由

在配置檔案application.yml中宣告:

springfox.docmentation.swagger.v2.path:/api-docs

這個path就是json的訪問request mapping,可以自定義,防止與自身程式碼衝突。
API doc的顯示路由是:http://localhost:8080/swagger-ui.html
啟動SpringBoot程式,訪問上面的網址,就能夠看到前文所展示的restful API的介面了。
我們可以在這裡輸入引數資訊進行測試:

插入圖片

相關推薦

Spring使用Springfoxswagger生成restful風格API

發現一位博主寫的特別棒 強烈推薦參考他的:大牛的網址 由於Spring Boot能夠快速開發、便捷部署等特性,相信有很大一部分Spring Boot的使用者會用來構建RESTful API。而我們構建RESTful API的目的通常都是由於多終端的原因,這些

SpringBoot使用Swagger生成RestFul規範API

j簡單介紹Swagger的作用: Swagger是為了描述一套標準的而且是和語言無關的REST API的規範。對於外部呼叫者來說,只需通過Swagger文件即可清楚Server端提供的服務,而不需去閱讀原始碼或介面文件說明。 官方網站為:http://swagger.io 中文網站:http

使用apidoc 生成Restful web Api

在專案開發過程中,總會牽扯到介面文件的設計與編寫,之前使用的都是office工具,寫一個文件,總也是不夠漂亮和直觀。好在git上的開源大神提供了生成文件的工具,so來介紹一下! 該工具是Nodejs的模組,請務必在使用前安裝好nodejs環境! 工具名稱:apiDoc Git地址:http

SpringBoot(二十)Swagger2-自動生成RESTful規範API

  Swagger2 方式,一定會讓你有不一樣的開發體驗:功能豐富 :支援多種註解,自動生成介面文件介面,支援在介面測試API介面功能;及時更新 :開發過程中花一點寫註釋的時間,就可以及時的更新API文件,省心省力;整合簡單 :通過新增pom依賴和簡單配置,內嵌於應用中就可同時釋

介面自動生成、使用apidoc 生成Restful web Api(express)

專案地址為: 專案地址 這個是自動生成網頁,我們就可以擺脫excel。 一.首先是使用node安裝apiDoc npm install apidoc -g 二.在需要生成介面的添加註釋 /** * @api {post} /v1/login

Jersey2+swagger組建restful風格api管理

1.jar包引入 <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server<

php學習之道:phpis_filefile_exist的差別,and推斷夾is_dir

文件 -m post 文件的 style 文件夾 原因 -a 文件名 在PHP中,is_file和file_isexist是有非常小差別的 1) is_file: $path ="/path/to/file/text.txt"; if(file_exis

nodejs restfulapi生成

1、apidoc的官網 http://apidocjs.com   2、安裝nodejs環境,安裝apidoc  npm install apidoc -g   3、在專案根目錄建立:apidoc.json;如: {   "name": "

[Swagger]swagger構建你的api

Swagger能成為最受歡迎的REST APIs文件生成工具之一,有以下幾個原因: Swagger 可以生成一個具有互動性的API控制檯,開發者可以用來快速學習和嘗試API。 Swagger 可以生成客戶端SDK程式碼用於各種不同的平臺上的實現。 Swagger 檔案可以在許多不同的

Java小技巧自動生成註釋、api

cmd 命令 javadoc的使用 win+R彈出執行視窗 輸入cmd回車,進入dos介面,輸入java -version,檢查java是否配置好。如下圖所示 配置好java後,我們新建一個含有公共類的java檔案,在裡面寫點東西。 然後儲存到資料夾test裡面

Maven學習總結(43)——利用javadoc外掛生成專案的API

在進行Java學習的時候,相信大家都看過線上或者下載的java api文件,可能是html格式或者chm格式的,其實這些參考文件也是很容易生成的,這裡介紹一個maven的外掛來實現專案程式碼文件的生成。

Spring MVC使用Swagger生成API完整專案示例Demo,swagger

轉載自:http://www.360doc.com/content/17/0914/17/16915_687184334.shtml    實際專案中非常需要寫文件,提高Java服務端和Web前端以及移動端的對接效率。   聽說Swagger這

Spring MVC使用Swagger生成API完整專案示例Demo,swagger-server-api

package cn.fansunion.swagger.serverapi.controller; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org

Spring Boot整合Swagger優雅的生成Restful風格API

一、自動生成API工具1、Swagger:是一個規範和完整的框架,用於生成、描述、呼叫和視覺化 RESTful 風格的 Web 服務。可以生成一個具有互動性的API控制檯,開發者可以用來快速學習和嘗試API。支援多種語言,如:Scala、Java、Ruby、PHP、JavaS

springmvc搭建swagger,並利用swagger json生成markdownhtml api

背景 服務端開發同學需要花很多時間編寫和維護大量的Rest介面文件,且往往介面修改後沒有及時同步文件,讓對接方和後續維護者一頭霧水。 有沒有一種方式可以相對容易地生成可讀性好的Rest文件,並且做到與程式碼同步? 目標 通過Swagger註釋自動生成Rest文件介面。 通過Sw

swagger uispring boot整合生成api

通過本篇文章,你可以學會通過配置生成介面文件,再也不用通過Postman來測試自己的介面啦。。。 一、環境 1. JAVA8 2. MAVEN 3.0.5 3. IDEA 2016.2.5 4. spring boot 1.4.1 二、相關依賴 <dependenc

Spring Boot 10 行程式碼構建 RESTful 風格應用

RESTful ,到現在相信已經沒人不知道這個東西了吧!關於 RESTful 的概念,我這裡就不做過多介紹了,傳統的 Struts 對 RESTful 支援不夠友好 ,但是 SpringMVC 對於 RESTful 提供了很好的支援,常見的相關注解有: @RestController @GetMapping

spring Boot】Spring@Controller@RestController之間的區別

處理 public 不同 esp 舉例 rest control tro adding spring Boot入手的第一天,看到例子中的@RestController ............. 相同點:都是用來表示Spring某個類的是否可以接收HTTP請求 不同點:@C

SpringIOCAOP的理解

ted program 條件 ogr class spring配置 所有 com 語法 IOC:控制反轉也叫依賴註入。利用了工廠模式。  為了方便理解,分解成每條以便記憶。 1.將對象交給容器管理,你只需要在spring配置文件總配置相應的bean,以及設置相關的屬性,讓

SpringIOCAOP的詳細解釋

獲得 當我 行為 bean spring 完成 耦合 模式 初始化 我們是在使用Spring框架的過程中,其實就是為了使用IOC,依賴註入,和AOP,面向切面編程,這兩個是Spring的靈魂。 主要用到的設計模式有工廠模式和代理模式。 IOC就是典型的工廠模式,通過sess