Springcloud-Gateway整合swagger3

Springcloud-Gateway整合swagger3

 

swagger的pom节点

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

聚合swagger-ui主要在于swagger提供的接口SwaggerResourcesProvider,他继承了Supplier<List<SwaggerResource>>,只有一个get()方法,从泛型也看的出来,他要get的是SwaggerResource,不难看出,这个就是Swagger资源了。

public class SwaggerResource implements Comparable<SwaggerResource> {
  private String name;
  private String url;
  private String swaggerVersion;
  省略set,get....
}

这个类就比较简单了

name:swagger 名

url: 请求路径,一般来说不用填,默认就行了

swaggerVersion: 版本

那我们需要做的就是自定义SwaggerResourcesProvider了

package com.lhf.fvsnewgateway.config;

import org.springframework.beans.factory.annotation.Autowired;
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.spi.DocumentationType;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

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

/**
 * <p></p>
 *
 * @author liuhf
 * @createTime 2021/5/20 17:13
 * @since 1.0
 */
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider {
    /**
     * RouteLocator,GatewayProperties这两个类都是springcloud提供的springbean对象直接注入即可
     */
    private final RouteLocator routeLocator;
    //gateway配置文件
    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()));
        //从配置文件中获取并配置SwaggerResource
        gatewayProperties.getRoutes().stream()
                //过滤路由
                .filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                //循环添加,从路由的断言中获取,一般来说路由都会配置断言Path信息,这就不多说了
                .forEach(route -> {
                    route.getPredicates().stream()
                            //获取Path信息
                            .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                            //开始添加SwaggerResource
                            .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
                                    predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                            .replace("**", "v2/api-docs?group=" + route.getId()))));
                });

        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(DocumentationType.OAS_30.getVersion());
        return swaggerResource;
    }

    @Autowired
    public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
    }

}


    @Autowired
    public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
    }

}

这里解释一下swaggerResource方法的第二个参数 location,在网上的一些文章中,并没有拼接group参数,这种情况只在模块儿中配置的swagger没有指定groupName情况下可以,如果配置了groupName,那这里就需要拼接group了,看下图的请求:

如果不配置的话是请不不到的会报这样的错误:

子服务的配置正常配置就行了:

package com.lhf.admin.boot.fvsadminboot.config;

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.RequestParameterBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

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

/**
 * <p></p>
 *
 * @author liuhf
 * @createTime 2021/5/20 9:50
 * @since 1.0
 */
@Configuration
@EnableOpenApi
public class SwaggerConfig {

    @Value("${swagger.enable}")
    private boolean enable;
    @Value("${swagger.host}")
    private String host;

    @Bean
    public Docket webApiConfig() {

        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("fvs-admin")
                .apiInfo(webApiInfo())
                .host(host)
                .globalRequestParameters(globalRequestParameters())
                .enable(enable)
                .select()
                .paths(PathSelectors.any())
                .build();

    }

    private ApiInfo webApiInfo() {
        return new ApiInfoBuilder()
                .title("后台管理admin接口文档")
                .description("本文档描述了网站微服务接口定义")
                .version("1.0")
                .contact(new Contact("lhf", "http://localhost:2626/fvs-admin", "lhf522626@163.com"))
                .build();
    }


    private List<RequestParameter> globalRequestParameters() {
        List<RequestParameter> requestParameters = new ArrayList<>();
        RequestParameterBuilder builder = new RequestParameterBuilder();
        requestParameters.add(
                builder.name("Authorization")
                        .required(false)
                        .in(ParameterType.HEADER)
                        .build()
        );
        return requestParameters;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }
}

因为将来我们是通过网关来访问的,所以host需要配置成网关的地址

DocumentationType,有三个版本,我建议用swagger2,主要的原因是swagger3会丢失网关的访问的前缀。比如我们通过网关访问/fvsSysUser/list,会自动添加服务名为前缀,请求应该是这样的http://localhost:2626/fvs-admin/fvsSysUser/list,但是,swagger3会丢失服务名请求就成了http://localhost:2626/fvsSysUser/list,这显然不是我们想要的结果,所以我还是建议用swagger2,他们两个ui差距是不大的,所以并不影响什么。

 

还有就是有的时候会遇到这样的错误:Unable to render this definition

造成这个的原因主要是访问不到服务的ui,可以看看gateway是否设置了权限问题,将权限放开就好了

文笔不好,请多见谅

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值