gateway整合swagger2

一、maven依赖

1、网关依赖(此处注册中心采用nacos)

 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
           <version>2.2.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
           <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

2、swagger2依赖

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>

二、网关配置文件

bootstrap.yml文件

spring:
  application:
    name: gateway
  profiles:
    active: local
    # 开启 Gateway 服务注册中心服务发现
  cloud:
    gateway:
      discovery:
        locator:
          enabled: on
          #使用服务名称的小写(服务名称不能带下划线)
          lower-case-service-id: on
    nacos:
      config:
        #配置文件后缀名
        file-extension: yaml
        refresh-enabled: true
  #允许覆盖已经存在的同名bean
  main:
    allow-bean-definition-overriding: true

bootstrap-local.yml文件

server:
  port: 8081
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        group: local
log:
  level: INFO
  #日志保存时间(天)
  maxHistory: 2
  #每个日志文件的大小
  maxSize: 10MB

logback-spring.xml文件(logback文件)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration>
 3     <springProperty scope="context" name="loglevel" source="log.level"/>
 4     <springProperty scope="context" name="maxHistory" source="log.maxHistory"/>
 5     <springProperty scope="context" name="maxSize" source="log.maxSize"/>
 6     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 7         <encoder>
 8             <pattern>%d{yyyy-MM-dd HH:mm:ss}[%level][%thread][%logger]-%msg%n</pattern>
 9             <charset>UTF-8</charset>
10         </encoder>
11     </appender>
12     <!-- Perf4J logger Appender -->
13     <appender name="DailyAndSizeRollAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
14         <file>logs/gateway.log</file>
15         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
16             <!-- rollover daily -->
17             <fileNamePattern>logs/lt_gateway.%i.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
18             <timeBasedFileNamingAndTriggeringPolicy
19                     class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
20                 <!-- or whenever the file size reaches 200MB -->
21                 <maxFileSize>${maxSize}</maxFileSize>
22             </timeBasedFileNamingAndTriggeringPolicy>
23             <maxHistory>${maxHistory}</maxHistory>
24         </rollingPolicy>
25         <encoder>
26             <pattern>%d{yyyy-MM-dd HH:mm:ss}[%level][%thread][%logger]-%msg%n</pattern>
27             <charset>UTF-8</charset>
28         </encoder>
29     </appender>
30 <appender name="logApiAccess" class="ch.qos.logback.core.rolling.RollingFileAppender">
31         <file>logs/api_access/access.log</file>
32         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
33             <!-- rollover daily -->
34             <fileNamePattern>logs/api_access/access.log.%i.%d{yyyy-MM-dd}.log.zip
35             </fileNamePattern>
36             <timeBasedFileNamingAndTriggeringPolicy
37                     class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
38                 <!-- or whenever the file size reaches 200MB -->
39                 <maxFileSize>200MB</maxFileSize>
40             </timeBasedFileNamingAndTriggeringPolicy>
41             <maxHistory>7</maxHistory>
42         </rollingPolicy>
43         <encoder>
44             <pattern>%msg%n</pattern>
45         </encoder>
46     </appender>
47     <!--监控指定的日志类 并输出到指定的文件中-->
48     <logger name="com.xx.xx.LogApiAccessUtil" level="${loglevel}">
49            <appender-ref ref="logApiAccess"/>
50      </logger>
51     <root level="${loglevel}">
52         <appender-ref ref="STDOUT"/>
53         <appender-ref ref="DailyAndSizeRollAppender"/>
54     </root>
55 </configuration>

三、swagger2配置类

1、获取不同微服务的提供者

 1 public static final String SWAGGER2URL  = "/v2/api-docs";
 2     private final RouteLocator routeLocator;
 3 
 4     @Value("${spring.application.name}")
 5     private String self;
 6 
 7     public SwaggerConfig(RouteLocator routeLocator) {
 8         this.routeLocator = routeLocator;
 9     }
10 
11     @Override
12     public List<SwaggerResource> get() {
13         List<SwaggerResource> resources = new ArrayList<>();
14         List<String> routeHosts = new ArrayList<>();
15         // 由于我的网关采用的是负载均衡的方式,因此我需要拿到所有应用的serviceId
16         // 获取所有可用的host:serviceId
17         routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
18                 .filter(route -> !self.equals(route.getUri().getHost()))
19                 .subscribe(route -> routeHosts.add(route.getUri().getHost()));
20 
21         // 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上
22         Set<String> dealed = new HashSet<>();
23         routeHosts.forEach(instance -> {
24             // 拼接url,样式为/serviceId/v2/api-info,当网关调用这个接口时,会自动通过负载均衡寻找对应的主机
25             String url = "/" + instance + SWAGGER2URL;
26             if (!dealed.contains(url)) {
27                 dealed.add(url);
28                 SwaggerResource swaggerResource = new SwaggerResource();
29                 swaggerResource.setUrl(url);
30                 swaggerResource.setName(instance);
31                 resources.add(swaggerResource);
32             }
33         });
34         return resources;
35     }

2、聚合接口类

 1 @RestController
 2 public class SwaggerHandler {
 3 
 4     @Autowired(required = false)
 5     private SecurityConfiguration securityConfiguration;
 6 
 7     @Autowired(required = false)
 8     private UiConfiguration uiConfiguration;
 9 
10     private final SwaggerResourcesProvider swaggerResources;
11 
12     @Autowired
13     public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
14         this.swaggerResources = swaggerResources;
15     }
16 
17     @GetMapping("/swagger-resources/configuration/security")
18     public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
19         return Mono.just(new ResponseEntity<>(
20                 Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
21     }
22 
23     @GetMapping("/swagger-resources/configuration/ui")
24     public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
25         return Mono.just(new ResponseEntity<>(
26                 Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
27     }
28 
29     @GetMapping("/swagger-resources")
30     public Mono<ResponseEntity> swaggerResources() {
31         return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
32     }
33 
34     @GetMapping("/")
35     public Mono<ResponseEntity> swaggerResourcesN() {
36         return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
37     }
38 
39     @GetMapping("/csrf")
40     public Mono<ResponseEntity> swaggerResourcesCsrf() {
41         return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
42     }
View Code

3、解决访问/v2/api/docs 404的问题

@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerConfig.SWAGGER2URL)) {
                return chain.filter(exchange);
            }
            ServerHttpRequest newRequest = request.mutate().build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

四、微服务的相关配置

1、maven依赖

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
           <version>2.2.1.RELEASE</version>
        </dependency>
<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
           <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
           <version>1.5.21</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
           <version>1.9.6</version>
        </dependency>

2、配置文件

bootstrap.yml文件

spring:
  application:
    name: dcjcgl
  profiles:
    active: local
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  servlet:
    multipart:
      #单文件大小
      max-file-size: 512MB
      #总上传文件大小
      max-request-size: 512MB
      enabled: true
      file-size-threshold: 0
  cloud:
    nacos:
      config:
        #配置文件后缀名
        file-extension: yaml
        refresh-enabled: true
  #允许覆盖已经存在的同名bean
  main:
    allow-bean-definition-overriding: true

bootstrap-local.yml文件

server:
  port: 8083
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        group: local
#日志配置
log:
  level: INFO
  #日志保存时间(天)
  maxHistory: 2
  #每个日志文件的大小
  maxSize: 10MB

3、配置类

@Configuration
@EnableSwagger2
public class SwaggerConfig {


    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xx.xx.web"))
                .paths(PathSelectors.any())
                .build();
    }

    public ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("xx模块相关接口")
                .description("用restful风格写接口")
                .termsOfServiceUrl("")
                .version("1.0")
                .build();
    }
原文地址:https://www.cnblogs.com/cq-yangzhou/p/13731368.html