未解决的坑:
1.Basic用不了,Bearer的引用方式跟以前有点不一样
2.gateway网关统一管理 集中文档只能用SWAGGER_2(2.0),不能用OAS_30(3.0.3)
3.引入基础包的bean不能使用 BeanFactoryAware(导致不能创建多个group)
替换
Springfox3配置
引入包
现在只需要一个包 springboot的,不像以前需要两个,当然可以单独引用两个也行3.0的,具体可以进入这个包里看
io.springfox
springfox-boot-starter
3.0.0
注解和访问地址 变更
由之前的 @EnableSwagger2 更改为 @EnableOpenApi,当然@EnableOpenAp可以放在配置类,也可以放在启动类上,项目访问地址从2.x的 http://localhost:8088/swagger-ui.html 到 3.x的 http://localhost:8088/swagger-ui/index.html 或 http://localhost:8088/swagger-ui/
注:@EnableSwagger2在springfox3版本依然可以继续使用
DocumentationType 变更
Docket构造函数中的DocumentationType指向更改:由之前的DocumentationType.SWAGGER_2 更改为 DocumentationType.OAS_30
注:DocumentationType.SWAGGER_2在springfox3版本依然可以继续使用
@Bean
public Docket createDocApi() {
return new Docket(DocumentationType.OAS_30)
.enable(swaggerProperties.getEnabled())
.apiInfo(buildApiInfo(swaggerProperties.getDocketConfig()))
.select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getDocketConfig().getBasePackage()))
.paths(buildPredicateSelector(swaggerProperties.getDocketConfig()))
.build()
.securitySchemes(Collections.singletonList(chooseAuthTypeScheme()))
.securityContexts(Collections.singletonList(chooseAuthTypeContext()))
;
}
断言Predicate变更
以前springfox2.x会默认引入guava 包,就像这个
com.google.guava
guava
20.0
compile
自从springfox官网github被其他老外提了issue吐槽guava落后,springfox3开始用了jdk8的Predicate,自此,springfox3只支持jdk8以上版本,这点要注意。
以下是我更新后predicate的配置:
private Predicate buildPredicateSelector(SwaggerProperties.DocketConfig config){
// base-path处理
List> basePath = new ArrayList<>();
for (String path : config.getBasePath()) {
basePath.add(PathSelectors.ant(path));
}
// exclude-path处理
List> excludePath = new ArrayList<>();
for (String path : config.getExcludePath()) {
excludePath.add(PathSelectors.ant(path));
}
// 当没有配置任何path的时候,解析/.*
if (config.getBasePath().isEmpty() || config.getBasePath() == null) {
//return PathSelectors.regex("/.*");
return PathSelectors.any().and(excludePath.stream().reduce(each -> true, (a,b) -> a.and(b.negate())));
}
//组装 base-path 和 exclude-path
return basePath.stream().reduce(each -> false, Predicate::or) //each为false原因是,如果是true,有任何or,都不会走右边
.and(excludePath.stream().reduce(each -> true, (a,b) -> a.and(b.negate())));
}
以上是springfox3的变更。
gateway网关实现集中化
说明
首先gateway默认是webflux,springfox2.x是没有整合webflux的(2.10除外),18年到现在两年没更新可能导致很多人都弃坑springfox,转openApi3了(另一个非官网组织)。而现在springfox3出现了,终于不用换包了。(主要是懒)
然后gateway这个服务同样引入上述包即可,只需引入,不用像2.10分两个注解 @EnableSwagger2WebMvc 和 @EnableSwagger2WebFlux,只需引入@EnableOpenApi注解即可。
Nacos 实现方式
/**
* 以nacos方式聚合各个服务的swagger接口文档, 直接获取nacos存活的服务
*
* @author lbj
* @date 2020/09/22 18:25
*/
@Primary
@Component
@ConditionalOnProperty(prefix = "myyshop.swagger.provider", name = "type", havingValue = "nacos", matchIfMissing = true)
public class NacosSwaggerResourceProvider implements SwaggerResourcesProvider {
/**
* swagger2默认的url后缀
*/
private static final String SWAGGER2URL = "/v2/api-docs";
private static final String OAS_30_URL = "/v3/api-docs";
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
/**
* 网关应用名称
*/
@Value("${spring.application.name}")
private String self;
@Override
public List get() {
List resources = new ArrayList<>();
String hasIpCount = "true";
String withInstances = "false";
String pageNo = "1";
String pageSize = "1000";
String httpUrlEx = "http://%s/nacos/v1/ns/catalog/services?hasIpCount=%s&withInstances=%s&pageNo=%s&pageSize=%s&serviceNameParam=&groupNameParam=%s&namespaceId=%s";
String httpUrl = String.format(httpUrlEx, nacosDiscoveryProperties.getServerAddr(), hasIpCount, withInstances, pageNo, pageSize, nacosDiscoveryProperties.getGroup(), nacosDiscoveryProperties.getNamespace());
ResponseEntity
Gateway RouteLocator 实现方式
/**
* 以gateway方式聚合各个服务的swagger接口文档(还可以加入healthy,去逐个匹配healthy,判断是否存活,活的话加入SwaggerResource列表,否则不加入)
*
* @author lbj
* @date 2020/09/22 18:25
*/
@Primary
@Component
@ConditionalOnProperty(prefix = "myyshop.swagger.provider", name = "type", havingValue = "gateway")
public class GatewaySwaggerResourceProvider implements SwaggerResourcesProvider {
/**
* swagger2默认的url后缀
*/
private static final String SWAGGER2URL = "/v2/api-docs";
private static final String OAS_30_URL = "/v3/api-docs";
/**
* 网关路由
*/
@Autowired
private RouteLocator routeLocator;
@Autowired
private GatewayProperties gatewayProperties;
/**
* 网关应用名称
*/
@Value("${spring.application.name}")
private String self;
@Override
public List get() {
List ds = gatewayProperties.getRoutes();
List resources = new ArrayList<>();
List routeHosts = new ArrayList<>();
// 获取所有可用的host:serviceId
routeLocator.getRoutes()
.filter(route -> route.getUri().getHost() != null)
.filter(route -> Objects.equals(route.getUri().getScheme(), "lb"))
// .filter(route -> !self.equals(route.getUri().getHost()))
.subscribe(route -> routeHosts.add(route.getUri().getHost()));
// 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上
Set dealed = new HashSet<>();
routeHosts.forEach(instance -> {
// 拼接url
String url = "/" + instance.toLowerCase() + SWAGGER2URL;
if (!dealed.contains(url)) {
dealed.add(url);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setUrl(url);
swaggerResource.setName(instance);
//swaggerResource.setSwaggerVersion("3.0.3");
resources.add(swaggerResource);
}
});
return resources;
}
}