<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Cloud集成Knife4j管理接口文檔

          共 21206字,需瀏覽 43分鐘

           ·

          2023-06-24 09:44

          ?Knife4j前身是swagger-bootstrap-ui,取名knife4j是希望她能像一把匕首一樣小巧,輕量,并且功能強悍,更名也是希望把她做成一個為Swagger接口文檔服務(wù)的通用性解決方案,不僅僅只是專注于前端Ui前端.雖然目前還只是在前端,但以后功能肯定不止于此。

          2.0版本主要是使用Vue+Ant Design對前端Ui進行重寫,該版本是真正的前后端分離版本,同時依賴于Vue的技術(shù)生態(tài),以后會有更多有趣的功能實現(xiàn),全方位滿足開發(fā)者的需要。

          Knife4j簡介

          核心功能

          該UI增強包主要包括兩大核心功能:文檔說明在線調(diào)試
          • 文檔說明 :根據(jù)Swagger的規(guī)范說明,詳細列出接口文檔的說明,包括接口地址、類型、請求示例、請求參數(shù)、響應(yīng)示例、響應(yīng)參數(shù)、響應(yīng)碼等信息,使用 Knife4j 能能根據(jù)該文檔說明,對該接口的使用情況一目了然。
          • 在線調(diào)試 :提供在線接口聯(lián)調(diào)的強大功能,自動解析當(dāng)前接口參數(shù),同時包含表單驗證,調(diào)用參數(shù)可返回接口響應(yīng)內(nèi)容、headers、Curl請求命令實例、響應(yīng)時間、響應(yīng)狀態(tài)碼等信息,幫助開發(fā)者在線調(diào)試,而不必通過其他測試工具測試接口是否正確,簡介、強大。

          UI增強

          Knife4j 在滿足以上功能的同時,還提供了文檔的增強功能,這些功能是官方 swagger-ui 所沒有的,每一個增強的功能都是貼合實際,考慮到開發(fā)者的實際開發(fā)需要,是必不可少的功能,主要包括:
          • 個性化配置 :通過個性化ui配置項,可自定義UI的相關(guān)顯示信息
          • 離線文檔:根據(jù)標(biāo)準(zhǔn)規(guī)范,生成的在線 markdown 離線文檔,開發(fā)者可以進行拷貝生成 markdown 接口文檔,通過其他第三方 markdown 轉(zhuǎn)換工具轉(zhuǎn)換成 html pdf ,這樣也可以放棄 swagger2markdown 組件
          • 接口排序 :自1.8.5后,ui支持了接口排序功能,例如一個注冊功能主要包含了多個步驟,可以根據(jù) Knife4j 提供的接口排序規(guī)則實現(xiàn)接口的排序,step化接口操作,方便其他開發(fā)者進行接口對接

          UI特點

          • markdown 形式展示文檔,將文檔的請求地址、類型、請求參數(shù)、示例、響應(yīng)參數(shù)分層次依次展示,接口文檔一目了然,方便開發(fā)者對接

          • 在線調(diào)試欄除了自動解析參數(shù)外,針對必填項著顏色區(qū)分,同時支持tab鍵快速輸入上下切換.調(diào)試時可自定義Content-Type請求頭類型

          • 個性化配置項,支持接口地址、接口description屬性、UI增強等個性化配置功能

          • 接口排序,支持分組及接口的排序功能

          • 支持 markdown 文檔離線文檔導(dǎo)出,也可在線查看離線文檔

          • 調(diào)試信息全局緩存,頁面刷新后依然存在,方便開發(fā)者調(diào)試

          • 以更人性化的treetable組件展示Swagger Models功能

          • 響應(yīng)內(nèi)容可全屏查看,針對響應(yīng)內(nèi)容很多的情況下,全屏查看,方便調(diào)試、復(fù)制

          • 文檔以多tab方式可顯示多個接口文檔

          • 請求參數(shù)欄請求類型、是否必填著顏色區(qū)分

          • 主頁中粗略統(tǒng)計接口不同類型數(shù)量

          • 支持接口在線搜索功能

          • 左右菜單和內(nèi)容頁可自由拖動寬度

          • 支持自定義全局參數(shù)功能,主頁包括header及query兩種類型

          • i18n國際化支持,目前支持:中文簡體、中文繁體、英文

          • JSR-303 annotations 注解的支持

          Knife4j集成

          對于Spring Cloud微服務(wù)集成,有2種不同的配置:網(wǎng)關(guān)微服務(wù)

          Spring Cloud Gateway網(wǎng)關(guān)

          我們的網(wǎng)關(guān)做了文檔聚合的作用,也就是將所有微服務(wù)文檔聚合到網(wǎng)關(guān)提供文檔統(tǒng)一入口,當(dāng)然你也可以單獨做一個“文檔聚合”服務(wù)??

          第一步:pom引入相關(guān)jar包

                
                  
                    <dependency>
                  
                
                
                      <groupId>com.github.xiaoymingroupId>
                
                
                      <artifactId>knife4j-spring-boot-starterartifactId>
                
                
                      <version>${knife4j.version}version>
                
                
                  
                    dependency>
                  
                
              

          ${knife4j.version}取最新的版本,我們使用的是2.0.2

          需要注意的是knife4j需要依賴lombok,如果沒有使用的話請增加下面的配置

                
                  
                    <dependency>
                  
                
                
                      <groupId>org.projectlombokgroupId>
                
                
                      <artifactId>lombokartifactId>
                
                
                      <version>1.18.4version>
                
                
                      <scope>providedscope>
                
                
                  
                    dependency>
                  
                
              

          第二步: 文檔聚合業(yè)務(wù)編碼

          在我們使用Spring Boot等單體架構(gòu)集成swagger項目時,是通過對包路徑進行業(yè)務(wù)分組,然后在前端進行不同模塊的展示,而在微服務(wù)架構(gòu)下,我們的一個服務(wù)就類似于原來我們寫的一個業(yè)務(wù)分組 springfox-swagger 提供的分組接口是 swagger-resource ,返回的是分組接口名稱、地址等信息


          在Spring Cloud微服務(wù)架構(gòu)下,我們需要重寫該接口,主要是通過網(wǎng)關(guān)的注冊中心動態(tài)發(fā)現(xiàn)所有的微服務(wù)文檔,代碼如下:

                
                  @Slf4j
                
                
                  
                    @Component
                  
                
                
                  
                    @Primary
                  
                
                
                  
                    @AllArgsConstructor
                  
                
                
                  public class SwaggerResourceConfig implements SwaggerResourcesProvider {
                
                
                  
                    
          private final RouteLocator routeLocator; private final GatewayProperties gatewayProperties;

          @Override public List get() { List resources = new ArrayList<>(); List routes = new ArrayList<>(); routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> { route.getPredicates().stream() .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") .replace("**", "v2/api-docs")))); });
          return resources; }
          private SwaggerResource swaggerResource(String name, String location) { log.info("name:{},location:{}",name,location); SwaggerResource swaggerResource = new SwaggerResource(); swaggerResource.setName(name); swaggerResource.setLocation(location); swaggerResource.setSwaggerVersion("2.0"); return swaggerResource; } }

          上面代碼為Knife4j官方提供,由于我們是使用了 k8s APIServer+ETCD 做的服務(wù)注冊中心并且支持了 ConfigMap 動態(tài)配置,必須做如下代碼改造下:

                
                  
                    /**
                  
                
                
                  
                     * @author James Tang
                  
                
                
                  
                     * @date Created in 2020/3/18 19:48
                  
                
                
                  
                     */
                  
                
                
                  @Slf4j
                
                
                  @Component
                
                
                  @Primary
                
                
                  @AllArgsConstructor
                
                
                  public class SwaggerResourceConfig implements SwaggerResourcesProvider {
                
                
                  
                    
          // private final RouteLocator routeLocator; // private final GatewayProperties gatewayProperties; private final InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository;
          private final String API_DOCS_ROUTE_ID_POSTFIX = "apidocs";
          @Override public List<SwaggerResource> get() { List<SwaggerResource> resources = new ArrayList<>(); // List routes = new ArrayList<>(); // routeLocator.getRoutes().subscribe(route -> { // log.info(route.toString()); // routes.add(route.getId()); // });
          Set<String> serviceGroups = Sets.newHashSet(); inMemoryRouteDefinitionRepository.getRouteDefinitions().subscribe(routeDefinition -> { log.info(routeDefinition.toString()); if (routeDefinition.getId().endsWith(API_DOCS_ROUTE_ID_POSTFIX)) { String[] tmpSplits = routeDefinition.getId().split("_"); if (tmpSplits.length > 1) { String groupName = tmpSplits[1]; if (!serviceGroups.contains(groupName)) { routeDefinition.getPredicates().stream() .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())).findFirst().ifPresent(predicateDefinition -> { String routePath = predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0"); String groupPath = routePath.substring(1).split("/")[0]; resources.add(swaggerResource(groupName, String.format("/%s/v2/api-docs?group=%s", groupPath, groupName))); }); serviceGroups.add(groupName); } } } });
          // gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> { // route.getPredicates().stream() // .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) // .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), // predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") // .replace("**", "v2/api-docs")))); // });
          return resources; }
          private SwaggerResource swaggerResource(String name, String location) { log.info("name:{},location:{}", name, location); SwaggerResource swaggerResource = new SwaggerResource(); swaggerResource.setName(name); swaggerResource.setLocation(location); swaggerResource.setSwaggerVersion("2.0"); return swaggerResource; } }

          文檔聚合相關(guān)接口:

                
                  
                    @RestController
                  
                
                
                  public class SwaggerHandler {
                
                
                  
                    
          @Autowired(required = false) private SecurityConfiguration securityConfiguration;
          @Autowired(required = false) private UiConfiguration uiConfiguration;
          private final SwaggerResourcesProvider swaggerResources;
          @Autowired public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { this.swaggerResources = swaggerResources; }

          @GetMapping("/swagger-resources/configuration/security") public Mono> securityConfiguration() { return Mono.just(new ResponseEntity<>( Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); }
          @GetMapping("/swagger-resources/configuration/ui") public Mono> uiConfiguration() { return Mono.just(new ResponseEntity<>( Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); }
          @GetMapping("/swagger-resources") public Mono swaggerResources() { return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); } }


          微服務(wù)接口

          下面我們看下消息服務(wù)做了什么配置?

          第一步:pom引入相關(guān)jar包

                
                  
                    <dependency>
                  
                
                
                      <groupId>org.projectlombokgroupId>
                
                
                      <artifactId>lombokartifactId>
                
                
                      <version>1.18.4version>
                
                
                      <scope>providedscope>
                
                
                  
                    dependency>
                  
                
                
                  
                    
                  
                
                
                  
                    <dependency>
                  
                
                
                      <groupId>io.springfoxgroupId>
                
                
                      <artifactId>springfox-swagger2artifactId>
                
                
                      <version>2.8.0version>
                
                
                  
                    dependency>
                  
                
                
                  
                    <dependency>
                  
                
                
                      <groupId>io.springfoxgroupId>
                
                
                      <artifactId>springfox-swagger-uiartifactId>
                
                
                      <version>2.8.0version>
                
                
                  
                    dependency>
                  
                
                
                  
                    <dependency>
                  
                
                
                      <groupId>io.springfoxgroupId>
                
                
                      <artifactId>springfox-bean-validatorsartifactId>
                
                
                      <version>2.8.0version>
                
                
                  
                    dependency>
                  
                
                
                  
                    
                  
                
                
                  
                    <dependency>
                  
                
                
                      <groupId>com.github.xiaoymingroupId>
                
                
                      <artifactId>knife4j-micro-spring-boot-starterartifactId>
                
                
                    <version>${knife4j.version}version>
                
                
                  
                    dependency>
                  
                
              

          ${knife4j.version}取最新的版本,我們使用的是2.0.2


          knife4j-micro-spring-boot-starter在服務(wù)內(nèi)不提供文檔入口,如果需要在消息服務(wù)直接能顯示文檔,請?zhí)鎿Q為knife4j-spring-boot-starter

          第二步 :增加@EnableKnife4j注解

                
                  /**
                
                
                   * @author James
                
                
                   * @date 19/4/2
                
                
                   */
                
                
                  @Configuration
                
                
                  @EnableKnife4j
                
                
                  @EnableSwagger2
                
                
                  @Import(BeanValidatorPluginsConfiguration.class)
                
                
                  public class SwaggerConfig {
                
                
                  
                    
          ...
          }

          好了,大功告成!

          bf9e3c689bcb18a2d29eb5d8fe27b0cd.webp

          注意點

          在集成Spring Cloud Gateway網(wǎng)關(guān)的時候,會出現(xiàn)沒有basePath的情況(即定義的例如/user、/order等微服務(wù)的前綴),這個情況在使用zuul網(wǎng)關(guān)的時候不會出現(xiàn)此問題。因此,在Gateway網(wǎng)關(guān)需要添加一個Filter實體Bean,代碼如下:

                
                  
                    @Component
                  
                
                
                  public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
                
                
                      private static final String HEADER_NAME = "X-Forwarded-Prefix";
                
                
                  
                    
          private static final String URI = "/v2/api-docs";
          @Override public GatewayFilter apply(Object config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); String path = request.getURI().getPath(); if (!StringUtils.endsWithIgnoreCase(path,URI )) { return chain.filter(exchange); } String basePath = path.substring(0, path.lastIndexOf(URI)); ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build(); ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); return chain.filter(newExchange); }; } }

          然后在配置文件指定這個filter

                
                  spring:
                
                
                    application:
                
                
                      name: service-doc
                
                
                    cloud:
                
                
                      gateway:
                
                
                        routes:
                
                
                          - id: service-user
                
                
                            uri: lb://service-user
                
                
                            predicates:
                
                
                              - Path=/user/**
                
                
                  
                              #            - Header=Cookie,Set-Cookie
                  
                
                
                            filters:
                
                
                              - SwaggerHeaderFilter
                
                
                              - StripPrefix=1
                
                
                          - id:  service-order
                
                
                            uri: lb://service-order
                
                
                            predicates:
                
                
                              - Path=/order/**
                
                
                            filters:
                
                
                              - SwaggerHeaderFilter  //指定filter
                
                
                              - StripPrefix=1
                
              

          這個“注意點”是官方提供的,我們并沒有遇到這個問題,也沒加這個配置,寫在這里希望遇到此類問題的人可以快速集成

          其實Swagger2文檔其實不止一種UI效果,在沒有接觸Knife4j之前,大家一般會使用springfox的幾個庫,下面是使用springfox-swagger-ui的效果圖,其實還是挺不錯的

          11fdd046aa6b8396b8ef9c5058493460.webp

          當(dāng)然Knife4jspringfox-swagger-ui并不排他,如果都喜歡的話可以一起使用

          Springfox-Swagger

          關(guān)于 SpringfoxSwagger 詳細使用,這里不過多敘述,可自行通過下面地址查閱

          • GitHub :? https://gith ub.com/springfox/springfox

          • 文檔 :http://springfox.io

          下面我們重點講解SpringfoxSwagger提供的與 K ni fe4j 有關(guān)的2個接口, K ni fe4j 包會根據(jù)下面2個接口來動態(tài)生成文檔

          • 分組接口: /swagg er-resources

          • 詳情實例接口: /v2/api-docs

          Swagger分組

          Swagger的分組接口是用后端配置不同的掃描包,將后端的接口,按配置的掃描包基礎(chǔ)屬性響應(yīng)給前端,看看分組接口響應(yīng)的json內(nèi)容:

                
                  [
                
                
                      {
                
                
                          "name": "分組接口",
                
                
                          "url": "/v2/api-docs?group=分組接口",
                
                
                          "swaggerVersion": "2.0",
                
                
                          "location": "/v2/api-docs?group=分組接口"
                
                
                      },
                
                
                      {
                
                
                          "name": "默認接口",
                
                
                          "url": "/v2/api-docs?group=默認接口",
                
                
                          "swaggerVersion": "2.0",
                
                
                          "location": "/v2/api-docs?group=默認接口"
                
                
                      }
                
                
                  ]
                
              

          在Springfox-Swagger有些較低的版本中,并沒有l(wèi)ocation屬性,高版本會有該屬性

          c2e929621eeaf2ba07446cfe58ea24d8.webp

          分組的后端Java配置代碼如下:

                
                  @Bean(value = "defaultApi")
                
                
                  public Docket defaultApi() {
                
                
                      ParameterBuilder parameterBuilder=new ParameterBuilder();
                
                
                      List parameters= Lists.newArrayList();
                
                
                      parameterBuilder.name("token").description("token令牌").modelRef(new ModelRef("String"))
                
                
                          .parameterType("header").defaultValue("abc")
                
                
                          .required(true).build();
                
                
                      parameters.add(parameterBuilder.build());
                
                
                  
                    
          return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .groupName("默認接口") .select() .apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.controller")) .paths(PathSelectors.any()) .build().globalOperationParameters(parameters) .securityContexts(Lists.newArrayList(securityContext(),securityContext1())).securitySchemes(Lists.newArrayList(apiKey(),apiKey1())); } @Bean(value = "groupRestApi") public Docket groupRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(groupApiInfo()) .groupName("分組接口") .select() .apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.group")) .paths(PathSelectors.any()) .build().securityContexts(Lists.newArrayList(securityContext(),securityContext1())).securitySchemes(Lists.newArrayList(apiKey(),apiKey1())); }

          詳情實例接口

          詳情實例接口是根據(jù)分組名稱動態(tài)獲取該組下配置的basePackage所有的接口描述信息,如下圖所示:

          d3ebbcfe1fb5c4302ef0d3cf57772407.webp

          理解這2個接口,就理解 Knife4j 是怎么回事了?? 大家最近安好,中國加油??
          瀏覽 28
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品999www | 欧美色图亚洲色图另类 | 国产成人自拍操屄熟 | www.草逼.vom | 免费人妻视频 |