接口文檔神器Swagger(下篇)

本文來自網易云社區


作者:李哲

二、Swagger-springmvc原理解析

上面介紹了如何將springmvc和springboot與swagger結合,通過簡單配置生成接口文檔,以及介紹了swagger提供的一些注解。下面將介紹swagger是如何做到與springmvc結合,自動生成接口文檔。

項目添加完成maven依賴后會加入swagger的依賴包,其中包括swagger- springmvc,swagger-annotations,swagger-models幾個依賴包。如下圖所示:

201809040948400e03308a-a090-4e3a-bc63-a4193865b4d0.jpg


其中,swagger-annotations是swagger提供給spring的注解包,上面說的注解基本都在這個包里面;swagger-models是swagger自己的model類,主要用于將注解解析成后面需要使用的model和一些model數據的處理。Swagger-springmvc是swagger接入spring的一個最重要的包,通過這個包的處理可以將添加的注解信息解析出來,自動生成接口需要的數據,最后通過url請求就能返回接口的信息,通過前端處理就可以在頁面上看到接口的信息。下面將重點分析swagger-springmvc包下的文件,本文中分析的是1.0.2版本的swagger-springmvc,其他版本會存在差異,請自行研究。

下圖是swagger-springmvc包結構,圖中標紅的兩個類是swagger的入口類,根據包的名字大致能猜出各個模塊的功能。這里先簡單介紹下,annotation包下只有一個注解類ApiIgnore,用于忽略不被swagger處理;authorization包下主要用于處理需要認證的接口,添加認證信息;configuration主要處理配置相關的操作,其中包含了程序的配置SpringSwaggerConfig類,該類是swagger的默認配置類,也可以自己編寫封裝去修改配置(一般都會編寫自己的配置類,設置一些api信息等)。Controller用于處理請求swagger文檔時返回數據給前端ui;core是整個處理過程的核心模塊,例如注解的解析,model的處理,一些處理過程中的策略等等;ordering包中是用于處理頁面顯示接口時,一些排序問題,其中的class都繼承了Ordering<T>類,實現了Comparator<T>接口;paths包下了類主要是處理前端訪問swagger接口時的路徑問題;plugin是swagger和spring結合的適配處理,也是程序的入口,相對spring來說,swagger就像一個插件接入spring中;scanners和readers兩個包主要是處理注解的獲取和掃描解析。swagger- springmvc包下的大致結構就是這樣的,看到這是不是覺得swagger沒那么神奇了,其實swagger做的兩件最主要的事就是:掃描解析注解變成相應的model,前端請求接口文檔時返回后臺處理好的接口信息。

2018090409485306e3b7a1-b215-47f8-a8cd-bb4a5a1401e3.jpg

馬上就要進入程序入口了,是不是有點激動呢?可能有的人會問,怎么知道Swagger PluginAdapter是程序的入口?配置的文件不是SpringSwaggerConfig嗎?進入源代碼就能找到答案,下面來看下SwaggerPluginAdapter類:

201809040949083fd3cfb2-0a44-460c-9226-3dea852f887b.jpg

這個類實現了ApplicationListener<ContextRefreshedEvent>接口,這是一個spring的接口,在spring的applicationcontext初始化完成后會執行onApplicationEvent方法,所以當spring啟動后,swagger就會被啟動。而SpringSwaggerConfig中使用了注解@configuration,會在spring啟動時進行swagger配置,在配置的時候會根據用戶自定義的配置進行設置,如果用戶沒有定義將用默認的配置。下面看下方法onApplicationEvent中的處理,如下圖所示,程序會先去判斷plugins是否存在,不存在直接使用默認的,如果配置中設置了plugin則使用配置中的SwaggerSpringMvcPlugin,最后都調用Swagger SpringMvcPlugin類的initialize方法。

20180904094921fcb61965-74a0-42cf-b019-5da4e93490e6.jpg


SwaggerSpringMvcPlugin是swagger和spring框架核心的類。有好多可配置的屬性,并且提供了相應的get與set方法。 在該類中,初始化了SwaggerApiResourceListing類(用于掃描RequestMappingHandler方法)的屬性。 當調用initialize()方法的時候,調用的則是SwaggerApiResourceListing類的initialize()方法。

20180904094937b6fd94e5-1a88-4efe-81a9-d6ccc80678a0.jpg

在initialize方法中主要做了兩件重要的事,第一通過apiListingReferenceScanner掃描所有的spring請求路徑(RequestMapping),過濾沒在配置類中設置的include Patterns,將掃描結果轉換為swagger自定義的model中。第二通過apiListingScanner類掃描第一步處理的每一個請求路徑,根據swagger的注解掃描每一個路徑對應的接口信息,最后將信息轉換為swagger中model并保存在swaggerCache中方便以后使用。

接下來分析具體的掃描過程,ApiListingReferenceScanner中的scan方法是調用該類中的scanSpringRequestMappings方法。在該方法中主要做的是根據spring中的Request MappingHandlerMapping找出符合條件的路徑并找出一些需要的信息保存起來。

20180904094955ef8c4b18-1d61-4d29-af73-d0bc2592a7fb.jpg

ApiListingScanner類中主要掃描每個請求路徑的具體接口信息,具體的掃描過程是通過命令模式執行。代碼中的每一種reader對應一種具體要執行的命令操作,對所有的請求路徑(RequestMapping)分別獲取MediaType、接口描述、接口model等信息。其中,MediaTypeReader是解析請求的MediaType類型,ApiDescriptionReader是解析接口的信息,ApiModelReader是解析接口的model(即ApiModel標注的類)。解析完成后分別將這些信息保存起來。ApiDescriptionReader中主要處理了請求路徑,然后通過ApiOperationReader去處理真正的接口信息。execute方法中可以看到分別去處理寫在接口上的注解。

20180904095008485c6921-9192-4c2c-b3f1-2e1f79e4a3d0.jpg


下面以一個OperationImplicitParametersReader為例介紹各種Reader是如何通過命令模式去處理對應的注解,其中通過AnnotationUtils.findAnnotation方法去查詢Api ImplicitParams注解去獲取接口上標注的參數信息,然后在繼承類SwaggerParameterReader中的execute方法中被調用。


20180904095023bc2e54e6-ec9b-4b97-b006-116b285c3ce1.jpg ?


2018090409504835867ee9-5543-4e88-bd9b-a0997391d35a.jpg

其他的注解也是通過這種方式被讀取出來,最后會將這些信息保存到SwaggerCache中,到此swagger處理代碼中的注解就已完成,當然過程中還有處理一些其他信息,例如,需要登錄認證的信息,處理接口的請求路徑以方便swagger本身請求接口時應用等等。但是這些處理好的信息是怎么能在前端頁面顯示的呢?接下來就研究下swagger如何在前端顯示接口信息。在swagger的默認配置類中有個ComponentScan注解標注需要掃描的包com.mangofactory.swagger.controllers,在該包下有一個controller叫DefaultSwaggerController,代碼如下:

20180904095106ccbcd4d0-ce63-41f6-ae9d-3e8cf78e2229.jpg

可以看到,swagger根據處理好的路徑對應返回相應的接口信息,從這里可以看到為什么解析的數據都放到SwaggerCache中,這樣后臺controller就可以返回請求的接口數據,通過前端頁面的解析就能在前端顯示接口的信息。下圖是前端代碼結構,通過index.html訪問接口信息。

20180904095121ddb9339e-0991-48f3-9b84-d4e73eb65c3a.jpg


至此swagger-springmvc是如何做到通過簡單注解配置就能實現自動生成接口文檔信息的原理就講完了,具體細節處理有興趣者可以自己研究。現在看來swagger也沒這么神奇了,但是其中用到的方法是值得我們學習使用的。例如,如何通過spring的方式獲取spring中管理的一些資源,命令模式,結合spring的插件開發等等。

三、Swagger其他功能

除了上面介紹的功能外,swagger還有一些其他功能,打開swagger的官網

https://swagger.io/可以看到除了介紹的功能,還有一些其他工具。

20180904095135bdf04fb3-6b0d-433b-8ffb-f4dc60586c7b.jpg


這里簡單介紹下swagger包含的其他功能,SwaggerEditor是一個swagger文檔編輯工具,通過該工具可以實現靜態接口文檔編寫,而且可以查看實時接口信息,上面一排按鈕可以實現保存,生成相關代碼等功能。如下圖所示:

20180904095146f837b359-1f72-4aa1-b639-900d5a658eb2.jpg

SwaggerCodeGen是一個代碼生成的工具,即通過該工具可以實現根據接口信息生成各種語言的接口代碼,可以生產前端、后臺、移動端代碼框架,可以通過?swagger- codegen-cli腳手架工具或者訪問github地址:https://github.com/swagger-api/swagger- codegen根據提示操作,里面也有示例。生成前端、移動端的代碼根據各語言通用的框架實現接口請求,例如android的代碼中使用okhttp請求接口數據;同時可以通過靜態接口文檔生成服務器端代碼,這樣會根據文檔中定義的接口信息和model生成相應的model和controller接口。通過SwaggerCodeGen生成的代碼在大型項目中可能不太實用,因為里面很多代碼不符合人們編碼習慣,但是在快速開發的小型項目中可以嘗試使用。

Swagger UI是展示接口頁面的前端框架,接口信息就是通過這個框架顯示出來的,所以不管是靜態接口文檔還是通過后臺代碼生成的接口信息都可以通過SwaggerUI來顯示。上面介紹的swagger結合springmvc使用中使用的就是Swagger UI來顯示接口頁面。下圖是swagger官網上的一個示例:

201809040952005d94382b-c961-4152-b4d2-0152c850b861.jpg


Swagger Inspector是一個測試接口工具,類似postman,主要用來測試請求返回情況,可以通過在線Swagger Inspector測試接口,基本測試是免費使用的。swagger還提供了一些高級功能,如安全掃描、復雜功能測試、load測試及監控數據等,可以根據需求付費使用。如下圖所示,Swagger Inspector也可以保存請求歷史,可以選擇請求生成swagger文檔。

201809040952138ddfc1af-e1a8-49a6-ad9a-bf3ccf3074d7.jpg


除此之外,swagger還提供了SwaggerHub,這是一個swagger倉庫,可以將文檔上傳保存,同時支持團隊協作,在線編輯,安全線上查閱等功能。Swagger還提供很多開源項目和活躍的社區,如果遇到問題可以去尋求幫助。

四、總結

本文主要介紹了swagger的簡介,如何在springmvc和springboot中使用swagger,swagger是如何在springmvc中發揮神奇功效的以及swagger的其他功能等。但是swagger也存在一些問題,例如需要在后臺代碼中加一些注解,過多的注解造成注解泛濫;接口文檔需要等到后臺接口寫好才能在前端展示,而一般開發可能需要先定義好接口,然后才開始寫代碼造成的流程混亂;要很深入的了解swagger需要時間和精力,對于忙業務的開發可能覺得不值得在上面花時間學習。其實對于這些問題都有很好的辦法解決,相比通過簡單學習就能方便的獲得接口信息而且不用反復更新文檔是很值得的一件事。對于接口文檔需要等后臺開發完才能展示的問題,可以先通過靜態的文檔書寫方式先寫文檔,之后再通過后臺接口方式實現。

通過上面的介紹,我們了解到swagger是一個功能非常強大的工具,如果能很好地利用這個工具將很大程度上提高我們的開發效率。雖然swagger之前也被爆出安全性問題,但這個問題在后續版本中得到了修復,所以趕快學習使用這個神器。由于時間倉促,如果文中有錯誤請諒解。

附(常用注解表):

201809040952273951845e-58c3-4b9e-8472-a1b50d338375.png



相關閱讀:接口文檔神器Swagger(上篇)

網易云大禮包:https://www.163yun.com/gift

本文來自網易云社區,經作者李哲授權發布


?


相關文章:
【推薦】?用SolrJ操作Solr做搜索(上篇)
【推薦】?【專家坐堂】四種并發編程模型簡介
【推薦】?視覺設計師的進化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282241.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282241.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282241.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php實現mysql分表

一、場景說明 1、為什么要進行分表 隨著數據量的不斷增大&#xff0c;一張表中的數據肯定也會越來越多&#xff0c;甚至達到百萬甚至千萬級。我們通常會通過搭建mysql集群&#xff08;主從同步&#xff09;&#xff0c;讀寫分離來實現優化數據庫查詢執行效率。 但是由于數據…

利用python進行數據分析D1——ch02引言

基礎的課程還沒學完&#xff0c;就來這本了&#xff0c;因為我平時的研究還是以數據的處理為主。把自己的事做好做細致讀了一下介紹部分&#xff0c;下載書里用到的數據&#xff0c;下載地址&#xff1a;https://github.com/wesm/pydata-book 如果你需要完成以下幾大類任務&…

記一次Memory Leak分析

起因&#xff1a;最近公司的一個web產品遇到了內存溢出&#xff0c;于是開始著手調查。調查&#xff1a;首先當務之急是找到那個或那些API導致Memory Leak&#xff0c;這個應該不難&#xff0c;根據監控分析&#xff0c;在內存上升時間段內有哪些API被訪問&#xff0c;再就是根…

【t057】任務分配

Time Limit: 1 second Memory Limit: 128 MB 【問題描述】 現有n個任務,要交給A和B完成。每個任務給A或給B完成&#xff0c;所需的時間分別為ai和bi。問他們完成所有的任務至少要多少時間。 【輸入格式】 第一行一個正整數n&#xff0c;表示有n個任務。 接下來有n行&#xf…

LeetCode 366. Find Leaves of Binary Tree

實質就是求每個節點的最大深度。用一個hash表記錄&#xff0c;最后輸出。 class Solution { public:unordered_map<TreeNode *,int> hash; // record the level from bottomvector<vector<int>> findLeaves(TreeNode* root) {vector<vector<int>>…

C#比較對象的相等性

對于相等的機制全部不同&#xff0c;這取決于比較的是引用類型還是值類型。以下分別介紹引用類型和值類型的相等性。1.比較引用類型的相等性 System.Object定義了三種不同的方法&#xff0c;來比較對象的相等性&#xff1a;ReferenceEquals()和兩個版本號的Equals()。再加上比較…

WebSocket教程

一、為什么需要 WebSocket&#xff1f; 初次接觸 WebSocket 的人&#xff0c;都會問同樣的問題&#xff1a;我們已經有了 HTTP 協議&#xff0c;為什么還需要另一個協議&#xff1f;它能帶來什么好處&#xff1f; 答案很簡單&#xff0c;因為 HTTP 協議有一個缺陷&#xff1a…

C# WPF十個美觀的界面設計展示

概述很多時候&#xff0c;我們設計的界面總是感覺缺乏美感&#xff0c;不是我們不會開發好看的界面&#xff0c;而是不知道怎么才算美觀&#xff0c;這時候我們不妨看看別人好的頁面是怎么做的.下面展示一些我覺得做的比較好的cs界面&#xff0c;希望能給大家在平時做界面設計時…

BZOJ3172: [Tjoi2013]單詞

【傳送門&#xff1a;BZOJ3172】 簡要題意&#xff1a; 給出n個單詞&#xff0c;你可以理解為將這些單詞變成一個個段落&#xff0c;然后求出每個單詞在所有段落中出現的次數 題解&#xff08;一&#xff09;&#xff1a; 剛開始不是很懂題目&#xff0c;結果發現將所有單詞看成…

MySQL5.6二進制軟件包編譯安裝詳解(三)

一、軟件環境 [rootlocalhost ~]# uname -r 3.10.0-862.el7.x86_64 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 二、安裝部署過程詳解 MySQL安裝3種方式&#xff1a;1>rpm包安裝應用文件默認安裝在/usr/local 目錄下2>源碼編譯需…

Java反射學習總結五(Annotation(注解)-基礎篇)

Annotation(注解)簡單介紹&#xff1a; 注解大家印象最深刻的可能就是JUnit做單元測試,和各種框架里的使用了。本文主要簡介一下注解的用法&#xff0c;下篇文章再深入的研究。 annotation并不直接影響代碼語義。可是它可以被看作類似程序的工具或者類庫。它會反過來對正在執行…

使用autok3s 安裝k3s 集群 和 kuboard 管理集群

一、k3s介紹1.1 什么是k3s?k3s 是經過 CNCF 認證的由 Rancher 公司開發維護的一個輕量級的 Kubernetes 發行版&#xff0c;內核機制還是和 k8s 一樣&#xff0c;但是剔除了很多外部依賴以及 K8s 的 alpha、beta 特性&#xff0c;同時改變了部署方式和運行方式&#xff0c;目的…

Nginx—— Rewrite規則的使用

一、使用場景 1、URL訪問跳轉 &#xff08;1&#xff09;頁面跳轉 &#xff08;2&#xff09;兼容性支持&#xff08;比如新老版本交替時&#xff0c;給老版本一條訪問道路&#xff09; &#xff08;3&#xff09;展示效果&#xff08;比如縮短前臺界面的地址欄的url&#…

java對象實例化的方式

java對象實例化的方式有以下幾種&#xff1a;1、使用new2、工廠模式3、反射4、clone()方法5、反序列化方式 /** 實現Cloneable和Serializable接口 */public class Book implements Cloneable, Serializable {private static final long serialVersionUID 1L; private Integer …

iOS-生成二維碼圖片【附中間帶有小圖標二維碼】(QRCode)

生成二維碼圖片也是項目中常用到的&#xff0c;二維碼的掃描Git上有很多好用的&#xff0c;這里主要說下二維碼的生成 1.普通二維碼 方法 /**生成二維碼QRStering&#xff1a;字符串imageFloat&#xff1a;二維碼圖片大小*/ (UIImage *)createQRCodeWithString:(NSString *)QRS…

libubox

lbubox是openwrt的一個核心庫&#xff0c;封裝了一系列基礎實用功能&#xff0c;主要提供事件循環&#xff0c;二進制格式處理&#xff0c;linux鏈表實現和一些JSON輔助處理。 它的目的是以動態鏈接庫方式來提供可重用的通用功能&#xff0c;給其他模塊提供便利和避免再造輪子。…

社區糾紛不斷:程序員何苦為難程序員

出品 | OSC開源社區&#xff08;ID&#xff1a;oschina2013)今年年初&#xff0c;我們報道“因為被多人侮辱大吼&#xff0c;Swift 之父正式退出 Swift 核心團隊”。諸如此類的“語言暴力”、“網絡暴力”事件在開源社區乃至整個 IT 社區屢見不鮮。多個技術社區&#xff0c;都出…

PHP 分布式集群中session共享問題以及session有效期的設置

一、Session的原理 以下以默認情況舉例&#xff1a; session_start();之后&#xff0c;會生成一個唯一的session_id&#xff0c;每一個用戶對應唯一一個session_id&#xff0c;每一個session_id對應服務器端的一個session文件。這個session文件存儲著當前session_id的信息&am…

[SDOI2009]Bill的挑戰——全網唯一 一篇容斥題解

全網唯一一篇容斥題解 Description Solution 看到這個題&#xff0c;大部分人想的是狀壓dp 但是我是個蒟蒻沒想到&#xff0c;就用容斥切掉了。 并且復雜度比一般狀壓低&#xff0c; &#xff08;其實這個容斥的算法&#xff0c;提出來源于ywy_c_asm&#xff09; &#xff08;然…

[NOIP2015提高組]運輸計劃

題目&#xff1a;BZOJ4326、洛谷P2680、Vijos P1983、UOJ#150、codevs4632、codevs5440。 題目大意&#xff1a;有一棵帶權樹&#xff0c;有一些運輸計劃&#xff0c;第i個運輸計劃從ai到bi&#xff0c;耗時為ai到bi的距離&#xff0c;所有運輸計劃一起開始。現在可以把一條邊權…