SpringCloudAlibaba篇(八)SpringCloudGateWay聚合swagger3、SpringBoot2.6.X整合swagger3+knife4j

本文介绍了如何在SpringCloud微服务架构中整合Swagger和Zipkin,实现API文档管理和分布式链路跟踪。首先,通过配置Swagger生成服务的API文档,并展示如何在网关端聚合所有微服务的Swagger文档。接着,详细讲解了Zipkin的集成步骤,用于收集和展示服务间的调用链路,帮助优化系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇,SpringCloudAlibaba篇(七)SpringCloud整合Zipkin分布式链路跟踪系统(SpringCloud+dubbo+Zipkin)

前言

Knife4j的前身是swagger-bootstrap-ui,前身swagger-bootstrap-ui是一个纯swagger-ui的ui皮肤项目

knife4j官网

服务端

构建依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

配置类

package top.fate.config;

import io.swagger.annotations.ApiOperation;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Response;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
 * @auther:Wangxl
 * @Emile:18335844494@163.com
 * @Time:2022/5/7 9:27
 */
@Configuration
@EnableOpenApi //注解启动用Swagger的使用,同时在配置类中对Swagger的通用参数进行配置
public class Swagger3Config implements EnvironmentAware {

    private String applicationName;

    private String applicationDescription;

    @Bean
    public Docket createRestApi(){
        //返回文档概要信息
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build()
//                .globalRequestParameters(getGlobalRequestParameters())
                .globalResponses(HttpMethod.GET,getGlobalResponseMessage())
                .globalResponses(HttpMethod.POST,getGlobalResponseMessage());
    }

    /*
    生成接口信息,包括标题,联系人等
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(applicationName+"接口文档")
                .description(applicationDescription)
                .contact(new Contact("fate急速出击","http://www.baidu.com","18335844494@163.com"))
                .version("1.0")
                .build();
    }


    /*
    封装全局通用参数
     */
    /*private List<RequestParameter> getGlobalRequestParameters() {
        List<RequestParameter> parameters=new ArrayList<>();
        parameters.add(new RequestParameterBuilder()
                .name("uuid")
                .description("设备uuid")
                .required(true)
                .in(ParameterType.QUERY)
                .query(q->q.model(m->m.scalarModel((ScalarType.STRING))))
                .required(false)
                .build());

        return parameters;
    }*/
    /*
    封装通用相应信息
     */
    private List<Response> getGlobalResponseMessage() {
        List<Response> responseList=new ArrayList<>();
        responseList.add(new ResponseBuilder().code("404").description("未找到资源").build());
        return responseList;
    }

    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(
            WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier,
            ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
            CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = webEndpointProperties.getDiscovery().isEnabled() &&
                (org.springframework.util.StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.applicationDescription = environment.getProperty("spring.application.description");
        this.applicationName = environment.getProperty("spring.application.name");
    }
}

配置文件

springfox:
  documentation:
    swagger-ui:
      enabled: true # false关闭swagger-ui界面 但不关闭openapi
spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER #springboot2.6.x如果不加该配置会报错

启动服务端

在这里插入图片描述

网关端 (聚合swagger,将所有微服务的文档集中到网关中)

添加依赖

<!-- knife4j-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

配置类

SwaggerHandler

package top.fate.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;

import java.util.Optional;

/**
 * @auther:Wangxl
 * @Emile:18335844494@163.com
 * @Time:2022/5/9 17:28
 */
@RestController
@RequestMapping("/swagger-resources")
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("/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

SwaggerHeaderFilter

package top.fate.config;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;

/**
 * @auther:Wangxl
 * @Emile:18335844494@163.com
 * @Time:2022/5/9 17:13
 */
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
    private static final String HEADER_NAME = "X-Forwarded-Prefix";

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
                return chain.filter(exchange);
            }
            String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

SwaggerProvider

package top.fate.config;

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
    public static final String API_URI = "/v2/api-docs";
    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;

    /**
     * 这个类是核心,这个类封装的是SwaggerResource,即在swagger-ui.html页面中顶部的选择框,选择服务的swagger页面内容。
     * RouteLocator:获取spring cloud gateway中注册的路由
     * RouteDefinitionLocator:获取spring cloud gateway路由的详细信息
     * RestTemplate:获取各个配置有swagger的服务的swagger-resources
     */
    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        //取出gateway的route
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        //结合配置的route-路径(Path),和route过滤,只获取有效的route节点
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                        .replace("/**", API_URI)))));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("3.0.0");
        return swaggerResource;
    }
}

配置文件

server:
  port: 30001
spring:
  cloud:
    gateway:
      enabled: true
      discovery:
        locator:
          lower-case-service-id: true
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**
          filters:
            - StripPrefix=1

启动

在这里插入图片描述

通过下拉框选择服务文档

在这里插入图片描述

<think>好的,用户想知道在Spring Cloud 2021中如何集成Knife4j来增强API文档功能。我需要先回顾一下相关的引用内容,确保信息准确。根据提供的引用,特别是引用[1]、[2]、[3]、[4]、[5],里面提到了Knife4j的依赖配置、Swagger整合步骤以及网关集成的方法。 首先,用户提到的是Spring Cloud 2021版本,所以需要确认对应的Spring Boot版本是否匹配。引用[2]中提到的环境信息是Spring Boot 2.6.3Spring Cloud Alibaba 2021.0.1.0,这可能与Spring Cloud 2021兼容。接下来,整合Knife4j通常需要在各个微服务中添加依赖,然后配置Swagger的相关信息,比如Docket和ApiInfo。引用[5]中还提到了Knife4j的注解使用,这也是需要注意的部分。 另外,如果涉及到网关聚合,比如Spring Cloud Gateway,可能需要引用[3]中的knife4j-gateway-spring-boot-starter依赖,并在网关模块进行配置,以聚合各个微服务的API文档。引用[4]中的聚合配置也是关键步骤,需要确保网关正确路由到各个服务的文档资源。 需要注意的是,用户的问题可能包括基本的整合步骤和网关的聚合配置,所以回答应该分步骤说明,并给出示例代码,如添加依赖、配置类、注解使用以及访问路径。同时,要确保引用的正确性,比如版本号是否适用于Spring Cloud 2021,避免出现版本冲突的问题。 最后,可能还需要提醒用户关于访问路径、注解的使用以及常见问题,比如跨域配置或资源放行,这些在引用[2]和[5]中都有提及。确保回答结构清晰,步骤明确,用户能够按照指导一步步完成集成。</think>以下是在Spring Cloud 2021中集成Knife4j实现API文档增强的完整解决方案: ### 一、基础环境配置 1. **版本要求** - Spring Boot2.6.x+ - Spring Cloud:2021.x+ - Knife4j:4.3.0+(支持OpenAPI 3.0规范) 2. **添加核心依赖** ```xml <!-- 微服务模块依赖 --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-spring-boot-starter</artifactId> <version>4.3.0</version> </dependency> <!-- 网关聚合依赖(可选) --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-gateway-spring-boot-starter</artifactId> <version>4.5.0</version> </dependency> ``` [^1][^3] ### 二、微服务配置步骤 1. **配置Swagger基础信息** ```java @Configuration @EnableOpenApi public class Knife4jConfig { @Bean public OpenAPI customOpenAPI() { return new OpenAPI() .info(new Info() .title("订单服务API") .version("1.0") .description("基于Spring Cloud 2021的API文档") .contact(new Contact().name("技术支持").url("http://example.com"))); } } ``` 2. **配置安全放行规则** ```yaml # application.yml knife4j: enable: true security: - name: Authorization type: apiKey in: header basic: enable: true username: doc password: 123456 ``` 3. **接口注解示例** ```java @Api(tags = "用户管理") @RestController @RequestMapping("/users") public class UserController { @ApiOperation(value = "创建用户", notes = "需要管理员权限") @PostMapping public User createUser(@RequestBody @Valid UserDTO userDTO) { // 实现逻辑 } } ``` [^5] ### 三、网关聚合配置(Spring Cloud Gateway) 1. **网关聚合配置类** ```java @Configuration public class GatewayKnife4jConfig { @Bean public RouterFunction<ServerResponse> routerFunction() { return RouterFunctions.route() .GET("/v3/api-docs/**", request -> ServerResponse.ok().bodyValue(new GatewaySwaggerResource())) .build(); } } ``` 2. **配置路由规则** ```yaml spring: cloud: gateway: routes: - id: order-service uri: lb://order-service predicates: - Path=/order/** filters: - name: SwaggerHeaderFilter args: names: X-Forwarded-Prefix ``` ### 四、访问验证 1. **访问路径** - 单个服务文档:`http://localhost:8080/doc.html` - 网关聚合文档:`http://gateway:port/doc.html#/home` 2. **安全认证** - 使用配置的basic账号登录(默认:doc/123456) - 支持OAuth2令牌验证[^2] ### 五、高级配置技巧 1. **自定义文档分组** ```java @Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("public-apis") .pathsToMatch("/public/**") .build(); } ``` 2. **响应结果增强** ```java @Schema(description = "标准响应结构") public class Result<T> { @Schema(description = "状态码", example = "200") private Integer code; @Schema(description = "业务数据") private T data; } ``` ### 常见问题排查 1. **文档不显示问题** - 检查`@EnableOpenApi`注解是否启用 - 验证包扫描路径是否正确 - 确认Spring Security配置放行`/v3/api-docs`和`/doc.html` 2. **版本兼容问题** - Spring Cloud 2021需使用Knife4j 4.3.0+ - 网关聚合需要单独配置路由规则[^3]
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fate急速出击

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值