swagger与springCloudGateway整合

swagger与springCloudGateway整合

单个服务swagger配置

增加依赖

<!-- swagger -->
<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>

增加swagger配置文件

@Configuration
@EnableSwagger2
public class SwaggerConfig{

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)   //主要api配置机制初始化为swagger规范2.0
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("换成你的controller包名"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot中使用Swagger2构建RESTful API")  // 标题
                .description("测试")  // 描述信息
                .termsOfServiceUrl("服务地址")  //服务网址
                .version("1.0") //版本号
                .build();
    }

}

解决静态资源无法访问的问题

@Configuration
public class CorsConfig extends WebMvcConfigurationSupport{
	/**
     * 解决swagger-ui.html 404无法访问的问题
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 解决静态资源无法访问
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/");
        // 解决swagger无法访问
        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        // 解决swagger的js文件无法访问
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

	@Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("PUT", "DELETE", "GET", "POST", "OPTIONS")
                .allowCredentials(true).maxAge(3600);

    }

}

接口参数说明

@ApiOperation(value = "测试swagger")
@ApiImplicitParams({
	@ApiImplicitParam(name = "deviceId",value = "设备ID",dataType = "string",paramType = "query",required = true),
	@ApiImplicitParam(name = "wifiId",value = "wifiID",dataType = "string",paramType = "query",required = true),
	@ApiImplicitParam(name = "token",value = "token",dataType = "string",paramType = "query",required = true)
})
@ApiResponses({@ApiResponse(code = 200,message = "OK",response = ResponseData.class)})

实现效果

swagger与springCloudGateway整合
swagger与springCloudGateway整合

springCloudGateway整合

增加依赖

<!-- swagger -->
<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>

swagger配置

共需增加三个配置文件

SwaggerProvider

@Component
@Primary
@AllArgsConstructor
public class GwSwaggerResourceProvider implements SwaggerResourcesProvider {
    public static final String API_URI = "/v2/api-docs";
    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(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("2.0");
        return swaggerResource;
    }
}

SwaggerHandler

@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

@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);
        };
    }
}

增加配置

#默认所有服务转发操作
spring.cloud.gateway.discovery.locator.enabled=true
#小写服务名
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
#path路由断言
spring.cloud.gateway.routes[0].id=springcloud-test
spring.cloud.gateway.routes[0].uri=lb://springcloud-test
spring.cloud.gateway.routes[0].predicates[0]=Path=/springcloud-test/**
spring.cloud.gateway.routes[0].filters[0].name=SwaggerHeaderFilter

spring.cloud.gateway.routes[1].id=springcloud-test2
spring.cloud.gateway.routes[1].uri=lb://springcloud-test2
spring.cloud.gateway.routes[1].predicates[0]=Path=/springcloud-test2/**
spring.cloud.gateway.routes[1].filters[0].name=SwaggerHeaderFilter

实现效果

swagger与springCloudGateway整合

注意

如配置了全局过滤,需增加白名单

上一篇:详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节


下一篇:在BTP上开发Fiori学习记录-注册Gateway Demo system账号