在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)

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

            發(fā)布人:天翼云開發(fā)者 時間:2023-04-07 來源:工程師 發(fā)布文章

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

            鏈接:

            https://www.ctyun.cn/developer/article/381687816880197?track=|cp:cz_bk|tgdy:wenzhang|ttjh:bokeshequ|key:bw308|pf:PC

            0.引言

            之前寫過一篇關(guān)于swagger(實際上是springfox)的使用指南(https://www.ctyun.cn/developer/article/371704742199365),涵蓋了本人在開發(fā)與學習的時候碰到的各種大坑。但由于springfox已經(jīng)不更新了,很多項目都在往springdoc遷移

            筆者也是花了一些時間試了一下這個號稱“把springfox按在地下摩擦”的springdoc究竟好不好使,本文就來簡單介紹下springdoc的使用以及優(yōu)劣勢

            1.引入maven依賴

            這里有個大坑一定要注意!??!

            如果你跟我一樣,現(xiàn)在使用的是springfox,但是想往springdoc遷移,結(jié)果試了一下發(fā)現(xiàn)還是springfox好用/懶得改那么多注解,還是想換回springfox,一定要把springdoc的maven依賴刪掉!??!不然springboot會默認你用的是springdoc,導(dǎo)致swagger界面出不來

            <dependency>

                        <groupId>org.springdoc</groupId>

                        <artifactId>springdoc-openapi-ui</artifactId>

                        <version>1.6.11</version>

             </dependency>

            2.springdoc配置類

            實際上springdoc的配置非常簡單,使用的是OpenAPI類與GroupedOpenApi來配置

            /**

             * SpringDoc API文檔相關(guān)配置

             * 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();

                }

                //可以創(chuàng)建不同的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)

            image.png 

            4.與SpringFox的注解對照

            image.png 

            5.SpringDoc基本注解用法

            這里轉(zhuǎn)載一個寫的非常全面的示例接口,原文可以去看: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 = "每頁數(shù)量") 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的結(jié)合

            如果項目中使用了SpringSecurity,需要做兩個配置來讓springdoc正常使用:

            1.在SpringSecurity配置類中放行白名單:"/v3/api-docs/**", "/swagger-ui/**"

            2.在SpringDoc配置中增加對應(yīng)內(nèi)容,如下:

            @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的設(shè)置,同時還有設(shè)置白名單

                            .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參數(shù)的問題

            實際上springfox也會有這個問題,使用對象作為query傳參的時候,頁面通常是這樣的:

            image.png 

            就沒有辦法逐個描述參數(shù),也不能逐個調(diào)試(只能用json調(diào)試),非常的麻煩;springdoc有一個解決這個問題非常方便的注解:@ParameterObject

            比如某一個控制器的入?yún)⑹?/span>User user,我們只需要在這前面加上注解變?yōu)椋篅ParameterObject User user 即可,結(jié)果如下;

            image.png 

            這里也有一個大坑:參數(shù)的類型可能會不正確,比如這里我們的id參數(shù)實際上是int,但顯示出來是string,這個時候就需要我們在User類的屬性中加上對應(yīng)的注解,比如:

            @Parameter(description = "id傳參",example = "6")

            再重啟UI就會發(fā)現(xiàn)參數(shù)類型正確了

            8.SpringDoc配置掃包范圍

            有的時候僅僅使用@Hidden并不能滿足我們的需要,因為可能需要配置不同group的controller類,這個時候就需要在配置類中取設(shè)置掃包范圍代碼如下:

            image.png 

            9.SpringDoc的優(yōu)劣勢

            優(yōu)勢:SpringDoc有著非常好看的UI,以及比Springfox更加完善的參數(shù)注解體系,看起來非常舒服,并且還在不斷更新與維護中

            劣勢:一些冷門功能還不完善,比如:

            a.有十個接口,他們的url是一樣的但是可以通過query參數(shù)來分別(如:@PostMapping(params = "action=QueryUsers"))這個時候springdoc只能通過掃包范圍配置,來寫多個GroupOpenApi來解決,非常的麻煩;springfox可以在docket創(chuàng)建的時候使用:docket.enableUrlTemplating(true); 這個方法即可解決

            b.springdoc的網(wǎng)絡(luò)配置可能會與springfox沖突,如果遷移,需要逐個嘗試網(wǎng)絡(luò)配置是否合適(主要是GsonHttpMessageConverter的配置)

            c.兼容性問題仍需要觀望,相對于springfox,springdoc的兼容性并沒有那么好,在許多時候可能會出現(xiàn)序列化的亂碼問題

             

            總結(jié):如果當前項目/工程已經(jīng)集成了完備的springfox,建議不要輕易嘗試遷移到springdoc,尤其是接口類型比較復(fù)雜、springfox配置docket比較多的項目;但如果是從頭開始的項目,由于接口相對比較簡單,可以采用springdoc,畢竟可以獲得更加清晰明了的顯示界面與參數(shù)解釋。

             


            *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



            關(guān)鍵詞: Java spring

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉