Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)

来源:https://www.cnblogs.com/developer-tianyiyun/archive/2023/04/07/17296936.html
-Advertisement-
Play Games

本文分享自天翼雲開發者社區@《Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)》,作者: 才開始學技術的小白 0.引言 之前寫過一篇關於swagger(實際上是springfox)的使用指南(https://www.ctyun.cn/developer/ar ...


 

本文分享自天翼雲開發者社區@《Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)》,作者: 才開始學技術的小白

 

 

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.

 */@Configurationpublic 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("https://github.com/")))

                .externalDocs(new ExternalDocumentation()

                        .description("SpringBoot項目")

                        .url("http://www.ctyun.com"));

    }

 

    @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.啟動

預設配置之後直接進入:http://localhost:8080/swagger-ui/index.html 即可

註意這裡與springfox略有不同(http://localhost:8080/swagger-ui.html)

 

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配置中增加對應內容,如下:

@Configurationpublic 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("https://gitlab.ctyun.cn/hpc/galaxy-parent/-/tree/v1.2.0")))

                .externalDocs(new ExternalDocumentation()

                        .description("彈性高性能計算(CTHPC)")

                        .url("http://www.ctyun.cn"))

                //以下是針對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,畢竟可以獲得更加清晰明瞭的顯示界面與參數解釋。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個非常簡單的小項目。 看到了楊旭大佬的教學視頻,自己跟著實現了一下,完善了一下游戲邏輯。 通過空格鍵進行控制。 游戲中可按 P 鍵 暫停/恢復 游戲 項目結構 · ├── Cargo.lock ├── Cargo.toml ├── src/ │ ├── main.rs │ ├──bird/ │ │ ...
  • 本文介紹了學習Spring源碼前需要掌握的核心知識點,包括IOC、AOP、Bean生命周期、初始化和Transaction事務。通過Hello World示例,講解瞭如何使用Spring,並指出了深入瞭解Spring內部機制的方向。 ...
  • 約束(Constraints) 上一章介紹了向模型中添加一些業務邏輯的能力。我們現在可以將按鈕鏈接到業務代碼,但如何防止用戶輸入錯誤的數據?例如,在我們的房地產模塊中,沒有什麼可以阻止用戶設置負預期價格。 odoo提供了兩種設置自動驗證恆定式的方法:Python約束 and SQL約束。 SQL 參 ...
  • Mybatis常見問題 1,大於號、小於號在sql語句中的轉換 使用 mybatis 時 sql 語句是寫在 xml 文件中,如果 sql 中有一些特殊的字元的話,比如< ,<=,>,>=等符號,會引起 xml 格式的錯誤,需要替換掉,或者不被轉義。 有兩種方法可以解決:轉義字元和標記 CDATA ...
  • SpringCloud Eureka-服務註冊與發現02 3.搭建EurekaServer集群-實現負載均衡&故障容錯 3.1為什麼需要集群EurekaServer? 微服務RPC遠程服務調用最核心的是高可用 如果註冊中心只有1個,如果出現故障,會導致整個服務環境不可用 解決辦法就是搭建Eureka ...
  • ps 命令速查備忘清單 Linux我們提供了一個名為 ps 的實用程式,用於查看與系統上的進程相關的信息,它是 Process Status 的縮寫這份 ps 命令備忘清單的快速參考列表,包含常用選項和示例。入門,為開發人員分享快速參考備忘單。 開發速查表大綱 入門 語法 示例 查看系統上的每個進程 ...
  • Perl語言線上運行編譯,是一款可線上編程編輯器,在編輯器上輸入Perl語言代碼,點擊運行,可線上編譯運行Perl語言,Perl語言代碼線上運行調試,Perl語言線上編譯,可快速線上測試您的Perl語言代碼,線上編譯Perl語言代碼發現是否存在錯誤,如果代碼測試通過,將會輸出編譯後的結果。 該線上工 ...
  • 簡介 ChatGPT Java版SDK開源地址:https://github.com/Grt1228/chatgpt-java ,目前收穫將近1000個star。 有bug歡迎朋友們指出,互相學習,所有咨詢全部免費。 最新版:1.0.10 <dependency> <groupId>com.unfb ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...