Spring Cloud Gateway 集成 Nacos、Knife4j

官方文档地址:Spring Cloud Gateway集成Knife4j
官方完整源码:https://gitee.com/xiaoym/swagger-bootstrap-ui-demo
自己搭建的源码地址:https://gitee.com/sheng-wanping/spring-boot-gateway

其实Knife4j官方文档写的很全,自己也是按照文档搭建的,这里记录一下自己的搭建过程:
由于公司使用的springboot版本较低,是2.1.3.RELEASE,因此其他组件使用了对应较低版本。

  • springboot版本2.1.3.RELEASE
  • nacos 版本2.1.4.RELEASE
  • gateway版本2.1.0.RELEASE
  • knife4j版本2.0.2

springboot 其他版本可以参考:spring-cloud-alibaba 版本对应说明

Spring Cloud Alibaba Version Spring Cloud Version Spring Boot Version
2022.0.0.0-RC* Spring Cloud 2022.0.0 3.0.0
2021.0.4.0* Spring Cloud 2021.0.4 2.6.11
2021.0.1.0 Spring Cloud 2021.0.1 2.6.3
2021.1 Spring Cloud 2020.0.1 2.4.2
2.2.10-RC1* Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.9.RELEASE Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.8.RELEASE Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.7.RELEASE Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.6.RELEASE Spring Cloud Hoxton.SR9 2.3.2.RELEASE
2.2.1.RELEASE Spring Cloud Hoxton.SR3 2.2.5.RELEASE
2.2.0.RELEASE Spring Cloud Hoxton.RELEASE 2.2.X.RELEASE
2.1.4.RELEASE Spring Cloud Greenwich.SR6 2.1.13.RELEASE
2.1.2.RELEASE Spring Cloud Greenwich 2.1.X.RELEASE
2.0.4.RELEASE(停止维护,建议升级) Spring Cloud Finchley 2.0.X.RELEASE
1.5.1.RELEASE(停止维护,建议升级) Spring Cloud Edgware 1.5.X.RELEASE

1、gateway网关配置

1.1 pom 配置

<!-- nacos 配置和注册中心 -->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- Gateway 网关相关 -->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- knife4j -->
<dependency>
   <groupId>com.github.xiaoymin</groupId>
   <artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>

2.2 配置文件

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {

    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;
    
    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> 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;
    }
}
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.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;
import java.util.Optional;

/**
 * @author xiaoymin
 * 2020年10月29日 18:38:01
 */
@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<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

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

    @GetMapping("/swagger-resources")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}
import org.apache.commons.lang.StringUtils;
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.web.server.ServerWebExchange;

/**
 * @author fsl
 * @description: SwaggerHeaderFilter
 * @date 2019-06-0310:47
 */
@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);
        };
    }
}

1.3 yaml 配置

application.yaml 主要是网关路由和跨域配置

spring:
  cloud:
    # Spring Cloud Gateway 配置项,对应 GatewayProperties 类
    gateway:
      # 路由配置项,对应 RouteDefinition 数组
      routes:
        - id: byzq-wq-api # 路由的编号
          uri: lb://byzq-wq # 根据服务名找
          predicates:
            - Path=/byzq-wq/** # 映射到对应路径
          filters:
            - StripPrefix=1 # 删除第一个路径段 /byzq-wq/api -> /api

        - id: byzq-yc-api # 路由的编号
          uri: lb://byzq-yc
          predicates:
            - Path=/byzq-yc/**
          filters:
            - StripPrefix=1
      # 全局跨域配置
      globalcors:
        cors-configurations: # 跨域配置列表
          '[/**]': # 匹配所有路径
            allowed-headers: "*" # 允许的请求头,*表示允许所有
            allowed-methods: # 允许的请求方法列表
              - GET
              - POST
              - PUT
              - DELETE
              - OPTIONS
            allowed-origins: "*" # 允许的请求来源,*表示允许所有
            exposed-headers: # 暴露的响应头列表
              - Authorization
              - Content-Type
            allow-credentials: true # 是否允许凭证传递,true表示允许

bootstrap.yaml 主要是nacos配置

注: nacos服务必须配置到bootstrap.yaml 里面才能被正确加载,因为执行顺序:bootstrap.yaml > ApplicationContext > application.yaml

server:
  port: 9999
  
# 需要在ApplicationContext创建之前加载配置文件
spring:
  application:
    name: byzq-gateway
  cloud:
    nacos:
      # nacos 服务注册
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: byzq-local # 命名空间
      # nacos 配置中心
      config:
        server-addr: 127.0.0.1:8848
        namespace: byzq-local # 命名空间
        group: DEFAULT_GROUP # 使用的 nacos 配置分组,默认为 DEFAULT_GROUP
        file-extension: yaml # 使用的 nacos 配置集的 dataId 的文件拓展名,默认为 properties

2、其他服务配置

2.1 pom 配置

<!-- nacos 配置和注册中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- springboot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Swagger 2 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-micro-spring-boot-starter</artifactId>
</dependency>

2.2 配置文件

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${swagger.enable}")
    private Boolean enable;
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enable)
                .apiInfo(apiInfo())
                .select()
                //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .apis(RequestHandlerSelectors.basePackage("org.example.controller")) // 替换为你的controller包路径
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("巴渝制气-扬尘") // API文档标题
                .description("巴渝制气-扬尘接口文档") // API文档描述
                .version("1.0") // API版本
                //.contact(new Contact("Your Name", "http://www.yourcompany.com/contact", "your.email@example.com")) // 维护者信息
                //.termsOfServiceUrl("http://www.yourcompany.com/terms") // 服务条款URL
                .license("Apache 2.0") // 许可证
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") // 许可证URL
                .build();
    }

}

2.3 yaml 配置

bootstrap.yaml 配置如下

spring:
  application:
    name: byzq-yc
  # 需要在ApplicationContext创建之前加载配置文件
  cloud:
    nacos:
      # nacos 服务注册
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: byzq-local # 命名空间
      # nacos 配置中心
      config:
        server-addr: 127.0.0.1:8848
        namespace: byzq-local # 命名空间
        group: DEFAULT_GROUP # 使用的 nacos 配置分组,默认为 DEFAULT_GROUP
        file-extension: yaml # 使用的 nacos 配置集的 dataId 的文件拓展名,默认为 properties

server:
  port: 8082
  
# 关闭swagger设置为false
swagger:
  enable: true

3、界面访问

启动服务访问 http://localhost:9999/doc.html 应该是能正常访问的。
在这里插入图片描述
如果你需要一套关于gateway+nacos+knife4j的项目可以看看的源码 https://gitee.com/sheng-wanping/spring-boot-gateway 里面还包括了 API网关权限校验、用户接口权限、单点登录,(因为公司要求轻量级因此没有引入spring security 和 jwt)如果觉得有帮到你的话可以帮忙点个 star,感谢!有什么疑问可以评论区留言或者私信。

4、其他

SpringBoot 集成 Nacos

相关推荐

  1. SpringBoot集成knife4j

    2024-06-06 05:32:01       33 阅读
  2. Springboot3 集成knife4j(swagger)

    2024-06-06 05:32:01       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 05:32:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 05:32:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 05:32:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 05:32:01       20 阅读

热门阅读

  1. 甜蜜约会网页制作html

    2024-06-06 05:32:01       8 阅读
  2. AWK使用总结

    2024-06-06 05:32:01       8 阅读
  3. 鲁教版八年级数学上册-笔记

    2024-06-06 05:32:01       8 阅读
  4. 有多少苹果用来分赃

    2024-06-06 05:32:01       9 阅读
  5. 枚举类型知识点

    2024-06-06 05:32:01       10 阅读
  6. Linux中挂载Windows Samba共享的指南

    2024-06-06 05:32:01       9 阅读
  7. python基于百度,哈工大等停用表进行的中文分词

    2024-06-06 05:32:01       8 阅读
  8. 个人关于ChatGPT的用法及建议

    2024-06-06 05:32:01       8 阅读
  9. HCIA-HarmonyOS Device Developer 课程大纲

    2024-06-06 05:32:01       10 阅读