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是否设置了权限问题,将权限放开就好了
文笔不好,请多见谅
736

被折叠的 条评论
为什么被折叠?



