Spring Cloud Gateway集成Swagger

1,498 阅读1分钟

基于SpringBoot 2.1.7.RELEASE + SpringCloud Greenwich.RELEASE

注意事项

不能依赖zipkin,会导致swagger host变成微服务真实IP,通过swagger测试请求地址不是gateway代理地址

1. 添加MySwaggerHandler

package com.zxk175.well.config;

import lombok.AllArgsConstructor;
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.ApiKeyVehicle;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import springfox.documentation.swagger.web.UiConfiguration;

/**
 * @author zxk175
 * @since 2019-07-11 11:23
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swagger-resources")
public class MySwaggerHandler {

    private SwaggerResourcesProvider swaggerResourcesProvider;


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

    @GetMapping("/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(new SecurityConfiguration(null, null, null, null, null, ApiKeyVehicle.HEADER, "api_key", ","), HttpStatus.OK));
    }

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

2. 添加MySwaggerProvider

package com.zxk175.well.config;

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinition;
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.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author zxk175
 * @since 2019-07-11 10:33
 */
@Primary
@Component
@AllArgsConstructor
public class MySwaggerProvider implements SwaggerResourcesProvider {

    private static final String API_URI = "/v2/api-docs";
    private PropertiesRouteDefinitionLocator propertiesRouteDefinition;


    @Override
    public List<SwaggerResource> get() {
        String lb = "lb://";
        List<SwaggerResource> swaggerResources = new ArrayList<>();

        // 取出application.yml配置的route
        propertiesRouteDefinition.getRouteDefinitions().subscribe(new Consumer<RouteDefinition>() {
            @Override
            public void accept(RouteDefinition routeDefinition) {
                // webSocket代理路由
                URI uri = routeDefinition.getUri();
                if (uri.toString().startsWith(lb)) {
                    swaggerResources.add(swaggerResource(routeDefinition.getId(), "/" + uri.getHost().toLowerCase() + API_URI));
                }
            }
        });

        return swaggerResources;
    }

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