乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      神器 SpringDoc 橫空出世!最適合 SpringBoot 的API文檔工具來了!

       昵稱10087950 2022-06-16 發(fā)布于江蘇

      圖片

      源 /         文/ 

      之前在SpringBoot項目中一直使用的是SpringFox提供的Swagger庫,上了下官網(wǎng)發(fā)現(xiàn)已經(jīng)有接近兩年沒出新版本了!前幾天升級了SpringBoot 2.6.x 版本,發(fā)現(xiàn)這個庫的兼容性也越來越不好了,有的常用注解屬性被廢棄了居然都沒提供替代!無意中發(fā)現(xiàn)了另一款Swagger庫SpringDoc,試用了一下非常不錯,推薦給大家!

      SpringDoc簡介

      SpringDoc是一款可以結(jié)合SpringBoot使用的API文檔生成工具,基于OpenAPI 3,目前在Github上已有1.7K+Star,更新發(fā)版還是挺勤快的,是一款更好用的Swagger庫!值得一提的是SpringDoc不僅支持Spring WebMvc項目,還可以支持Spring WebFlux項目,甚至Spring Rest和Spring Native項目,總之非常強大,下面是一張SpringDoc的架構(gòu)圖。

      圖片

      使用

      接下來我們介紹下SpringDoc的使用,使用的是之前集成SpringFox的mall-tiny-swagger項目,我將把它改造成使用SpringDoc。

      集成

      首先我們得集成SpringDoc,在pom.xml中添加它的依賴即可,開箱即用,無需任何配置。

      <!--springdoc 官方Starter-->
      <dependency>
          <groupId>org.springdoc</groupId>
          <artifactId>springdoc-openapi-ui</artifactId>
          <version>1.6.6</version>
      </dependency>

      從SpringFox遷移

      • 我們先來看下經(jīng)常使用的Swagger注解,看看SpringFox的和SpringDoc的有啥區(qū)別,畢竟對比已學過的技術(shù)能該快掌握新技術(shù);
      SpringFoxSpringDoc
      @Api@Tag
      @ApiIgnore@Parameter(hidden = true)or@Operation(hidden = true)or@Hidden
      @ApiImplicitParam@Parameter
      @ApiImplicitParams@Parameters
      @ApiModel@Schema
      @ApiModelProperty@Schema
      @ApiOperation(value = "foo", notes = "bar")@Operation(summary = "foo", description = "bar")
      @ApiParam@Parameter
      @ApiResponse(code = 404, message = "foo")ApiResponse(responseCode = "404", description = "foo")
      • 接下來我們對之前Controller中使用的注解進行改造,對照上表即可,之前在@Api注解中被廢棄了好久又沒有替代的description屬性終于被支持了!
      /**
       * 品牌管理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));
          }
      }
      • 接下來進行SpringDoc的配置,使用OpenAPI來配置基礎(chǔ)的文檔信息,通過GroupedOpenApi配置分組的API文檔,SpringDoc支持直接使用接口路徑進行配置。
      /**
       * SpringDoc API文檔相關(guān)配置
       * Created by macro on 2022/3/4.
       */

      @Configuration
      public class SpringDocConfig {
          @Bean
          public OpenAPI mallTinyOpenAPI() {
              return new OpenAPI()
                      .info(new Info().title("Mall-Tiny API")
                              .description("SpringDoc API 演示")
                              .version("v1.0.0")
                              .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning")))
                      .externalDocs(new ExternalDocumentation()
                              .description("SpringBoot實戰(zhàn)電商項目mall(50K+Star)全套文檔")
                              .url("http://www."));
          }

          @Bean
          public GroupedOpenApi publicApi() {
              return GroupedOpenApi.builder()
                      .group("brand")
                      .pathsToMatch("/brand/**")
                      .build();
          }

          @Bean
          public GroupedOpenApi adminApi() {
              return GroupedOpenApi.builder()
                      .group("admin")
                      .pathsToMatch("/admin/**")
                      .build();
          }
      }

      結(jié)合SpringSecurity使用

      • 由于我們的項目集成了SpringSecurity,需要通過JWT認證頭進行訪問,我們還需配置好SpringDoc的白名單路徑,主要是Swagger的資源路徑;
      /**
       * SpringSecurity的配置
       * Created by macro on 2018/4/26.
       */

      @Configuration
      @EnableWebSecurity
      @EnableGlobalMethodSecurity(prePostEnabled = true)
      public class SecurityConfig extends WebSecurityConfigurerAdapter {                                              

          @Override
          protected void configure(HttpSecurity httpSecurity) throws Exception {
              httpSecurity.csrf()// 由于使用的是JWT,我們這里不需要csrf
                      .disable()
                      .sessionManagement()// 基于token,所以不需要session
                      .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                      .and()
                      .authorizeRequests()
                      .antMatchers(HttpMethod.GET, // Swagger的資源路徑需要允許訪問
                              "/",   
                              "/swagger-ui.html",
                              "/swagger-ui/",
                              "/*.html",
                              "/favicon.ico",
                              "/**/*.html",
                              "/**/*.css",
                              "/**/*.js",
                              "/swagger-resources/**",
                              "/v3/api-docs/**"
                      )
                      .permitAll()
                      .antMatchers("/admin/login")// 對登錄注冊要允許匿名訪問
                      .permitAll()
                      .antMatchers(HttpMethod.OPTIONS)//跨域請求會先進行一次options請求
                      .permitAll()
                      .anyRequest()// 除上面外的所有請求全部需要鑒權(quán)認證
                      .authenticated();
              
          }

      }
      • 然后在OpenAPI對象中通過addSecurityItem方法和SecurityScheme對象,啟用基于JWT的認證功能。
      /**
       * SpringDoc API文檔相關(guān)配置
       * Created by macro on 2022/3/4.
       */

      @Configuration
      public class SpringDocConfig {
          private static final String SECURITY_SCHEME_NAME = "BearerAuth";
          @Bean
          public OpenAPI mallTinyOpenAPI() {
              return new OpenAPI()
                      .info(new Info().title("Mall-Tiny API")
                              .description("SpringDoc API 演示")
                              .version("v1.0.0")
                              .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning")))
                      .externalDocs(new ExternalDocumentation()
                              .description("SpringBoot實戰(zhàn)電商項目mall(50K+Star)全套文檔")
                              .url("http://www."))
                      .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")));
          }
      }

      測試

      • 接下來啟動項目就可以訪問Swagger界面了,訪問地址:http://localhost:8088/swagger-ui.html
      圖片
      • 我們先通過登錄接口進行登錄,可以發(fā)現(xiàn)這個版本的Swagger返回結(jié)果是支持高亮顯示的,版本明顯比SpringFox來的新;
      圖片
      • 然后通過認證按鈕輸入獲取到的認證頭信息,注意這里不用加bearer前綴;
      圖片
      • 之后我們就可以愉快地訪問需要登錄認證的接口了;
      圖片
      • 看一眼請求參數(shù)的文檔說明,還是熟悉的Swagger樣式!
      圖片

      常用配置

      SpringDoc還有一些常用的配置可以了解下,更多配置可以參考官方文檔。

      springdoc:
        swagger-ui:
          # 修改Swagger UI路徑
          path: /swagger-ui.html
          # 開啟Swagger UI界面
          enabled: true
        api-docs:
          # 修改api-docs路徑
          path: /v3/api-docs
          # 開啟api-docs
          enabled: true
        # 配置需要生成接口文檔的掃描包
        packages-to-scan: com.macro.mall.tiny.controller
        # 配置需要生成接口文檔的接口路徑
        paths-to-match: /brand/**,/admin/**

      總結(jié)

      在SpringFox的Swagger庫好久不出新版的情況下,遷移到SpringDoc確實是一個更好的選擇。今天體驗了一把SpringDoc,確實很好用,和之前熟悉的用法差不多,學習成本極低。而且SpringDoc能支持WebFlux之類的項目,功能也更加強大,使用SpringFox有點卡手的朋友可以遷移到它試試!

      參考資料

      • 項目地址:https://github.com/springdoc/springdoc-openapi
      • 官方文檔:https:///

      項目源碼地址

      https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-springdoc

      一鍵三連「分享」、「點贊」和「在看」

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多