Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)
本文分享自天翼雲開發者社群 @《Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)》,作者: 才開始學技術的小白
連結:
https://www.ctyun.cn/developer/article/381687816880197?track=|cp:cz_bk|tgdy:wenzhang|ttjh:bokeshequ|key:bw308|pf:PC
0.引言
之前寫過一篇關於 swagger(實際上是springfox)的使用指南(https://www.ctyun.cn/developer/article/371704742199365),涵蓋了本人在開發與學習的時候碰到的各種大坑。但由於springfox已經不更新了,很多專案都在往springdoc遷移
筆者也是花了一些時間試了一下這個號稱 “把springfox按在地下摩擦”的springdoc究竟好不好使,本文就來簡單介紹下springdoc的使用以及優劣勢
1.引入maven依賴
這裡有個大坑一定要注意!!!
如果你跟我一樣,現在使用的是 springfox,但是想往springdoc遷移,結果試了一下發現還是springfox好用/懶得改那麼多註解,還是想換回springfox, 一定要把 springdoc的maven依賴刪掉!!!不然springboot會預設你用的是springdoc,導致swagger介面出不來
< dependency >
< groupId > org . springdoc </ groupId >
< artifactId > springdoc - openapi - ui </ artifactId >
< version > 1.6.11 </ version >
</ dependency >
2.springdoc配置類
實際上 springdoc的配置非常簡單,使用的是OpenAPI類與GroupedOpenApi來配置
/**
* SpringDoc API文件相關配置
* Created by macro on 2023/02/02.
*/ @Configuration public class SpringDocConfig {
@Bean
public OpenAPI mallTinyOpenAPI () {
return new OpenAPI ()
. info ( new Info (). title ( "CTYUN API" )
. description ( "SpringDoc API 演示" )
. version ( "v1.0.0" )
. license ( new License (). name ( "Apache 2.0" ). url ( " )))
. externalDocs ( new ExternalDocumentation ()
. description ( "SpringBoot專案" )
. url ( " ));
}
@Bean
public GroupedOpenApi adminApi () {
return GroupedOpenApi . builder ()
. group ( "admin" )
. pathsToMatch ( "/**" )
. build ();
}
//可以建立不同的GroupedOpenApi來判斷不同的controller
@Bean
public GroupedOpenApi userApi () {
return GroupedOpenApi . builder ()
. group ( "user" )
. pathsToMatch ( "/user/**" )
. build ();
}}
3.啟動
預設配置之後直接進入: 即可
注意這裡與 springfox略有不同()
4.與SpringFox的註解對照
5.SpringDoc基本註解用法
這裡轉載一個寫的非常全面的示例介面,原文可以去看: https://blog.csdn.net/zhenghongcs/article/details/123812583
/**
* 品牌管理Controller
* Created by macro on 2019/4/19.
*/ @Tag( name = "PmsBrandController" , description = "商品品牌管理" )@Controller@RequestMapping( "/brand" ) public class PmsBrandController {
@Autowired
private PmsBrandService brandService ;
private static final Logger LOGGER = LoggerFactory . getLogger ( PmsBrandController . class );
@Operation( summary = "獲取所有品牌列表" , description = "需要登入後訪問" )
@RequestMapping( value = "listAll" , method = RequestMethod . GET )
@ResponseBody
public CommonResult < List < PmsBrand >> getBrandList () {
return CommonResult . success ( brandService . listAllBrand ());
}
@Operation( summary = "新增品牌" )
@RequestMapping( value = "/create" , method = RequestMethod . POST )
@ResponseBody
@PreAuthorize( "hasRole('ADMIN')" )
public CommonResult createBrand (@RequestBody PmsBrand pmsBrand ) {
CommonResult commonResult ;
int count = brandService . createBrand ( pmsBrand );
if ( count == 1 ) {
commonResult = CommonResult . success ( pmsBrand );
LOGGER . debug ( "createBrand success:{}" , pmsBrand );
} else {
commonResult = CommonResult . failed ( "操作失敗" );
LOGGER . debug ( "createBrand failed:{}" , pmsBrand );
}
return commonResult ;
}
@Operation( summary = "更新指定id品牌資訊" )
@RequestMapping( value = "/update/{id}" , method = RequestMethod . POST )
@ResponseBody
@PreAuthorize( "hasRole('ADMIN')" )
public CommonResult updateBrand (@PathVariable( "id" ) Long id , @RequestBody PmsBrand pmsBrandDto , BindingResult result ) {
CommonResult commonResult ;
int count = brandService . updateBrand ( id , pmsBrandDto );
if ( count == 1 ) {
commonResult = CommonResult . success ( pmsBrandDto );
LOGGER . debug ( "updateBrand success:{}" , pmsBrandDto );
} else {
commonResult = CommonResult . failed ( "操作失敗" );
LOGGER . debug ( "updateBrand failed:{}" , pmsBrandDto );
}
return commonResult ;
}
@Operation( summary = "刪除指定id的品牌" )
@RequestMapping( value = "/delete/{id}" , method = RequestMethod . GET )
@ResponseBody
@PreAuthorize( "hasRole('ADMIN')" )
public CommonResult deleteBrand (@PathVariable( "id" ) Long id ) {
int count = brandService . deleteBrand ( id );
if ( count == 1 ) {
LOGGER . debug ( "deleteBrand success :id={}" , id );
return CommonResult . success ( null );
} else {
LOGGER . debug ( "deleteBrand failed :id={}" , id );
return CommonResult . failed ( "操作失敗" );
}
}
@Operation( summary = "分頁查詢品牌列表" )
@RequestMapping( value = "/list" , method = RequestMethod . GET )
@ResponseBody
@PreAuthorize( "hasRole('ADMIN')" )
public CommonResult < CommonPage < PmsBrand >> listBrand (@RequestParam( value = "pageNum" , defaultValue = "1" )
@Parameter( description = "頁碼" ) Integer pageNum ,
@RequestParam( value = "pageSize" , defaultValue = "3" )
@Parameter( description = "每頁數量" ) Integer pageSize ) {
List < PmsBrand > brandList = brandService . listBrand ( pageNum , pageSize );
return CommonResult . success ( CommonPage . restPage ( brandList ));
}
@Operation( summary = "獲取指定id的品牌詳情" )
@RequestMapping( value = "/{id}" , method = RequestMethod . GET )
@ResponseBody
@PreAuthorize( "hasRole('ADMIN')" )
public CommonResult < PmsBrand > brand (@PathVariable( "id" ) Long id ) {
return CommonResult . success ( brandService . getBrand ( id ));
}}
6.與SpringSecurity的結合
如果專案中使用了 SpringSecurity,需要做兩個配置來讓springdoc正常使用:
1.在SpringSecurity配置類中放行白名單:"/v3/api-docs/**", "/swagger-ui/**"
2.在SpringDoc配置中增加對應內容,如下:
@Configuration public class SpringDocConfig {
private static final String SECURITY_SCHEME_NAME = "BearerAuth" ;
@Bean
public OpenAPI managerOpenAPI () {
return new OpenAPI ()
. info ( new Info (). title ( "Galaxy-Cluster-Manager後端介面文件" )
. description ( "提供給前端介面(portal)的介面文件" )
. version ( "v1.0.0" )
. license ( new License (). name ( "galaxy 1.2.0" ). url ( " )))
. externalDocs ( new ExternalDocumentation ()
. description ( "彈性高效能運算(CTHPC)" )
. url ( " ))
//以下是針對SpringSecurity的設定,同時還有設定白名單
. addSecurityItem ( new SecurityRequirement (). addList ( SECURITY_SCHEME_NAME ))
. components ( new Components ()
. addSecuritySchemes ( SECURITY_SCHEME_NAME ,
new SecurityScheme ()
. name ( SECURITY_SCHEME_NAME )
. type ( SecurityScheme . Type . HTTP )
. scheme ( "bearer" )
. bearerFormat ( "JWT" )));
}
@Bean
public GroupedOpenApi publicApi () {
return GroupedOpenApi . builder ()
. group ( "portal" )
. pathsToMatch ( "/api/**" )
. build ();
}
}
7.SpringDoc使用物件作為Query引數的問題
實際上 springfox也會有這個問題,使用物件作為query傳參的時候,頁面通常是這樣的:
就沒有辦法逐個描述引數,也不能逐個除錯(只能用 json除錯),非常的麻煩;springdoc有一個解決這個問題非常方便的註解:@ParameterObject
比如某一個控制器的入參是 User user,我們只需要在這前面加上註解變為:@ParameterObject User user 即可,結果如下;
這裡也有一個大坑:引數的型別可能會不正確,比如這裡我們的 id引數實際上是int,但顯示出來是string,這個時候就需要我們在User類的屬性中加上對應的註解 ,比如:
@Parameter(description = "id傳參",example = "6")
再重啟 UI就會發現引數型別正確了
8.SpringDoc配置掃包範圍
有的時候僅僅使用 @Hidden並不能滿足我們的需要,因為可能需要配置不同group的controller類,這個時候就需要在配置類中取設定掃包範圍程式碼如下:
9.SpringDoc的優劣勢
優勢: SpringDoc有著非常好看的UI,以及比Springfox更加完善的引數註解體系,看起來非常舒服,並且還在不斷更新與維護中
劣勢:一些冷門功能還不完善,比如:
a.有十個介面,他們的url是一樣的但是可以透過query引數來分別(如:@PostMapping(params = "action=QueryUsers"))這個時候springdoc只能透過掃包範圍配置,來寫多個GroupOpenApi來解決,非常的麻煩;springfox可以在docket建立的時候使用:docket.enableUrlTemplating(true); 這個方法即可解決
b.springdoc的網路配置可能會與springfox衝突,如果遷移,需要逐個嘗試網路配置是否合適(主要是GsonHttpMessageConverter的配置)
c.相容性問題仍需要觀望,相對於springfox,springdoc的相容性並沒有那麼好,在許多時候可能會出現序列化的亂碼問題
總結:如果當前專案 /工程已經整合了完備的springfox,建議不要輕易嘗試遷移到springdoc,尤其是介面型別比較複雜、springfox配置docket比較多的專案;但如果是從頭開始的專案,由於介面相對比較簡單,可以採用springdoc,畢竟可以獲得更加清晰明瞭的顯示介面與引數解釋。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70014251/viewspace-2944055/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring Boot 整合 SpringDoc Swagger 3Spring BootSwagger
- 使用Springdoc OpenAPI替代SpringFox提供微服務API文件 – PiotrSpringAPI微服務
- 擁抱 OpenAPI 3:springdoc-openapi 食用指南APISpring
- SpringBoot3整合SpringDoc實現線上介面文件Spring Boot
- Swagger之外的選擇Swagger
- 神器 SpringDoc 橫空出世!最適合 SpringBoot 的API文件工具來了!Spring BootAPI
- jQuery入門-DOM/$/選擇器jQuery
- 今天談談.NET與Java,入門語言的選擇Java
- 區塊鏈開發入門如何選擇程式語言?區塊鏈
- Spring Boot整合Springfox Swagger3和簡單應用Spring BootSwagger
- 排序演算法入門:選擇排序排序演算法
- 如何選擇新媒體學習模式?如何入門新媒體運營模式
- 【Python入門教程】如何選擇合適的Python培訓機構?Python
- Java入門系列-08-選擇結構Java
- 排序演算法入門之「選擇排序」排序演算法
- Java入門培訓班怎麼選擇Java
- 程式設計師入門選擇書籍學習的利與弊程式設計師
- Python與Golang對比,如何選擇?PythonGolang
- 資料庫入門之RDS選擇原則資料庫
- webpack4入門筆記——打包模式選擇Web筆記模式
- SDL3 入門(4):選擇圖形引擎
- springfox-swagger-ui 在二級目錄下的路徑問題SpringSwaggerUI
- .Net Core微服務入門全紀錄(完結)——Ocelot與Swagger微服務Swagger
- Kafka 與 RabbitMQ 如何選擇使用哪個?KafkaMQ
- Hadoop基礎入門之發行版本的選擇Hadoop
- CSS入門十二:選擇器的優先順序CSS
- 為什麼很多人入門選擇Python爬蟲?Python爬蟲
- 如何選擇CDN
- .net webapi 入門之註冊swagger服務WebAPISwagger
- 開發?測試?新人入IT行業如何選擇?行業
- C語言快速入門教程1快速入門 2指令 3條件選擇C語言
- DevOps 與平臺工程:企業該如何選擇?dev
- 如何選擇AI晶片?AI晶片
- 如何選擇代理IP?
- 如何選擇jquery版本jQuery
- 新手入門的方向如何抉擇,懇求指點
- 新人該怎麼入門Python 多少人會選擇學PythonPython
- Redis 入門 - C#|.NET Core客戶端庫六種選擇RedisC#客戶端