Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
ec280224
提交
ec280224
authored
3月 04, 2023
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
基于老版本,实现 Spring Cloud Gateway 文档
上级
59c6963f
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
165 行增加
和
199 行删除
+165
-199
pom.xml
yudao-gateway/pom.xml
+3
-2
SpringDocConfiguration.java
.../iocoder/yudao/gateway/config/SpringDocConfiguration.java
+0
-35
SwaggerHandler.java
...java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java
+54
-54
SwaggerProvider.java
...ava/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java
+102
-102
application.yaml
yudao-gateway/src/main/resources/application.yaml
+6
-6
没有找到文件。
yudao-gateway/pom.xml
浏览文件 @
ec280224
...
...
@@ -57,8 +57,9 @@
</dependency>
<dependency>
<groupId>
org.springdoc
</groupId>
<artifactId>
springdoc-openapi-webflux-ui
</artifactId>
<groupId>
com.github.xiaoymin
</groupId>
<!-- 接口文档 -->
<artifactId>
knife4j-spring-boot-starter
</artifactId>
<version>
3.0.3
</version>
</dependency>
<!-- RPC 远程调用相关 -->
...
...
yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/config/SpringDocConfiguration.java
deleted
100644 → 0
浏览文件 @
59c6963f
package
cn
.
iocoder
.
yudao
.
gateway
.
config
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springdoc.core.GroupedOpenApi
;
import
org.springframework.cloud.gateway.route.RouteDefinition
;
import
org.springframework.cloud.gateway.route.RouteDefinitionLocator
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Lazy
;
import
java.util.ArrayList
;
import
java.util.List
;
@Slf4j
@Configuration
public
class
SpringDocConfiguration
{
private
static
final
String
SERVER_NAME_SUFFIX
=
"-api"
;
@Bean
@Lazy
(
false
)
public
List
<
GroupedOpenApi
>
apis
(
RouteDefinitionLocator
locator
)
{
List
<
GroupedOpenApi
>
groups
=
new
ArrayList
<>();
List
<
RouteDefinition
>
definitions
=
locator
.
getRouteDefinitions
().
collectList
().
block
();
for
(
RouteDefinition
definition
:
definitions
)
{
log
.
info
(
"id: "
+
definition
.
getId
()
+
" "
+
definition
.
getUri
().
toString
());
}
definitions
.
stream
()
.
filter
(
routeDefinition
->
routeDefinition
.
getId
().
matches
(
".*"
+
SERVER_NAME_SUFFIX
))
.
forEach
(
routeDefinition
->
{
String
name
=
routeDefinition
.
getId
().
replaceAll
(
SERVER_NAME_SUFFIX
,
""
);
GroupedOpenApi
.
builder
().
pathsToMatch
(
"/"
+
name
+
"/**"
).
group
(
name
).
build
();
});
return
groups
;
}
}
yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java
浏览文件 @
ec280224
//
package cn.iocoder.yudao.gateway.swagger;
//
//
//
import org.springframework.beans.factory.annotation.Autowired;
//
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.*;
//
//
import javax.annotation.Resource;
//
import java.util.List;
//
import java.util.Optional;
//
/
//
**
//
* Swagger Controller
//
*
//
* @author zxliu
//
* @date 2022-10-25 11:24
//
*/
//
@RestController
//
@RequestMapping("/swagger-resources")
//
public class SwaggerHandler {
//
//
@Resource
//
private SwaggerResourcesProvider swaggerResources;
//
//
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // 只有 @Autowired 可以实现可选注入
//
@Autowired(required = false)
//
private SecurityConfiguration securityConfiguration;
//
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // 只有 @Autowired 可以实现可选注入
//
@Autowired(required = false)
//
private UiConfiguration uiConfiguration;
//
//
@GetMapping("")
//
public Mono<ResponseEntity<List<SwaggerResource>>> swaggerResources() {
//
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
//
}
//
//
@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));
//
}
//
//
}
package
cn
.
iocoder
.
yudao
.
gateway
.
swagger
;
import
org.springframework.beans.factory.annotation.Autowired
;
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.*
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.Optional
;
/**
* Swagger Controller
*
* @author zxliu
* @date 2022-10-25 11:24
*/
@RestController
@RequestMapping
(
"/swagger-resources"
)
public
class
SwaggerHandler
{
@Resource
private
SwaggerResourcesProvider
swaggerResources
;
@SuppressWarnings
(
"SpringJavaAutowiredFieldsWarningInspection"
)
// 只有 @Autowired 可以实现可选注入
@Autowired
(
required
=
false
)
private
SecurityConfiguration
securityConfiguration
;
@SuppressWarnings
(
"SpringJavaAutowiredFieldsWarningInspection"
)
// 只有 @Autowired 可以实现可选注入
@Autowired
(
required
=
false
)
private
UiConfiguration
uiConfiguration
;
@GetMapping
(
""
)
public
Mono
<
ResponseEntity
<
List
<
SwaggerResource
>>>
swaggerResources
()
{
return
Mono
.
just
((
new
ResponseEntity
<>(
swaggerResources
.
get
(),
HttpStatus
.
OK
)));
}
@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
));
}
}
yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java
浏览文件 @
ec280224
//
package cn.iocoder.yudao.gateway.swagger;
//
//
import cn.hutool.core.collection.CollUtil;
//
import cn.hutool.core.util.StrUtil;
//
import lombok.extern.slf4j.Slf4j;
//
import org.springframework.cloud.gateway.config.GatewayProperties;
//
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
//
import org.springframework.cloud.gateway.route.RouteDefinition;
//
import org.springframework.cloud.gateway.support.NameUtils;
//
import org.springframework.context.annotation.Primary;
//
import org.springframework.stereotype.Component;
//
import springfox.documentation.swagger.web.SwaggerResource;
//
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
//
//
import javax.annotation.Resource;
//
import java.util.ArrayList;
//
import java.util.HashSet;
//
import java.util.List;
//
import java.util.Set;
//
/
//
**
//
* Swagger 资源的 Provider 实现类
//
*
//
* @author zxliu
// * @dat
e 2022-10-25 11:23
//
*/
//
@Component
//
@Primary
//
@Slf4j
//
public class SwaggerProvider implements SwaggerResourcesProvider {
//
//
@Resource
//
private GatewayProperties gatewayProperties;
//
//
/**
//
* 获得 SwaggerResource 列表
//
*
//
* @return SwaggerResource 列表
//
*/
//
@Override
//
public List<SwaggerResource> get() {
//
// 将 RouteDefinition 转换成 SwaggerResource
//
List<SwaggerResource> resources = new ArrayList<>();
//
Set<String> serviceNames = new HashSet<>(); // 已处理的服务名,避免重复
//
gatewayProperties.getRoutes().forEach(route -> {
//
// 已存在的服务,直接忽略
//
String serviceName = route.getUri().getHost();
//
if (StrUtil.isEmpty(serviceName)) {
//
return;
//
}
//
if (!serviceNames.add(serviceName)) {
//
return;
//
}
//
//
// 获得 Path PredicateDefinition
//
String path = getRoutePath(route);
//
if (path == null) {
//
return;
//
}
//
//
// 重要:构建最终的 SwaggerResource 对象
//
resources.add(buildSwaggerResource(serviceName, path));
//
});
//
return resources;
//
}
//
//
private SwaggerResource buildSwaggerResource(String name, String location) {
//
SwaggerResource swaggerResource = new SwaggerResource();
//
swaggerResource.setName(name);
//
swaggerResource.setLocation(location);
// swaggerResource.setSwaggerVersion("2.0
");
//
return swaggerResource;
//
}
//
//
/**
//
* 获得路由的 Path
//
*
//
* ① 输入:
//
* predicates:
//
* - Path=/admin-api/system/**
//
* ② 输出:
// * /admin-api/system/v2
/api-docs
//
*
//
* @param route 路由
//
* @return 路由
//
*/
//
private String getRoutePath(RouteDefinition route) {
//
PredicateDefinition pathDefinition = CollUtil.findOne(route.getPredicates(),
//
predicateDefinition -> "Path".equals(predicateDefinition.getName()));
//
if (pathDefinition == null) {
//
log.info("[get][Route({}) 没有 Path 条件,忽略接口文档]", route.getId());
//
return null;
//
}
//
String path = pathDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0");
//
if (StrUtil.isEmpty(path)) {
//
log.info("[get][Route({}) Path 的值为空,忽略接口文档]", route.getId());
//
return null;
//
}
// return path.replace("/**", "/v2
/api-docs");
//
}
//
//
}
package
cn
.
iocoder
.
yudao
.
gateway
.
swagger
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.util.StrUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cloud.gateway.config.GatewayProperties
;
import
org.springframework.cloud.gateway.handler.predicate.PredicateDefinition
;
import
org.springframework.cloud.gateway.route.RouteDefinition
;
import
org.springframework.cloud.gateway.support.NameUtils
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.stereotype.Component
;
import
springfox.documentation.swagger.web.SwaggerResource
;
import
springfox.documentation.swagger.web.SwaggerResourcesProvider
;
import
javax.annotation.Resource
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
/**
* Swagger 资源的 Provider 实现类
*
* @author zxliu
* @sinc
e 2022-10-25 11:23
*/
@Component
@Primary
@Slf4j
public
class
SwaggerProvider
implements
SwaggerResourcesProvider
{
@Resource
private
GatewayProperties
gatewayProperties
;
/**
* 获得 SwaggerResource 列表
*
* @return SwaggerResource 列表
*/
@Override
public
List
<
SwaggerResource
>
get
()
{
// 将 RouteDefinition 转换成 SwaggerResource
List
<
SwaggerResource
>
resources
=
new
ArrayList
<>();
Set
<
String
>
serviceNames
=
new
HashSet
<>();
// 已处理的服务名,避免重复
gatewayProperties
.
getRoutes
().
forEach
(
route
->
{
// 已存在的服务,直接忽略
String
serviceName
=
route
.
getUri
().
getHost
();
if
(
StrUtil
.
isEmpty
(
serviceName
))
{
return
;
}
if
(!
serviceNames
.
add
(
serviceName
))
{
return
;
}
// 获得 Path PredicateDefinition
String
path
=
getRoutePath
(
route
);
if
(
path
==
null
)
{
return
;
}
// 重要:构建最终的 SwaggerResource 对象
resources
.
add
(
buildSwaggerResource
(
serviceName
,
path
));
});
return
resources
;
}
private
SwaggerResource
buildSwaggerResource
(
String
name
,
String
location
)
{
SwaggerResource
swaggerResource
=
new
SwaggerResource
();
swaggerResource
.
setName
(
name
);
swaggerResource
.
setLocation
(
location
);
swaggerResource
.
setSwaggerVersion
(
"3.0.3
"
);
return
swaggerResource
;
}
/**
* 获得路由的 Path
*
* ① 输入:
* predicates:
* - Path=/admin-api/system/**
* ② 输出:
* /admin-api/system/v3
/api-docs
*
* @param route 路由
* @return 路由
*/
private
String
getRoutePath
(
RouteDefinition
route
)
{
PredicateDefinition
pathDefinition
=
CollUtil
.
findOne
(
route
.
getPredicates
(),
predicateDefinition
->
"Path"
.
equals
(
predicateDefinition
.
getName
()));
if
(
pathDefinition
==
null
)
{
log
.
info
(
"[get][Route({}) 没有 Path 条件,忽略接口文档]"
,
route
.
getId
());
return
null
;
}
String
path
=
pathDefinition
.
getArgs
().
get
(
NameUtils
.
GENERATED_NAME_PREFIX
+
"0"
);
if
(
StrUtil
.
isEmpty
(
path
))
{
log
.
info
(
"[get][Route({}) Path 的值为空,忽略接口文档]"
,
route
.
getId
());
return
null
;
}
return
path
.
replace
(
"/**"
,
"/v3
/api-docs"
);
}
}
yudao-gateway/src/main/resources/application.yaml
浏览文件 @
ec280224
...
...
@@ -12,37 +12,37 @@ spring:
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/admin-api/system/**
filters
:
-
RewritePath=/admin-api/system/v
2/api-docs, /v2/api-docs
# 配置,保证转发到 /v2
/api-docs
-
RewritePath=/admin-api/system/v
3/api-docs, /v3/api-docs
# 配置,保证转发到 /v3
/api-docs
-
id
:
system-app-api
# 路由的编号
uri
:
grayLb://system-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/app-api/system/**
filters
:
-
RewritePath=/app-api/system/v
2/api-docs, /v2
/api-docs
-
RewritePath=/app-api/system/v
3/api-docs, /v3
/api-docs
-
id
:
infra-admin-api
# 路由的编号
uri
:
grayLb://infra-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/admin-api/infra/**
filters
:
-
RewritePath=/admin-api/infra/v
2/api-docs, /v2
/api-docs
-
RewritePath=/admin-api/infra/v
3/api-docs, /v3
/api-docs
-
id
:
infra-app-api
# 路由的编号
uri
:
grayLb://infra-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/app-api/infra/**
filters
:
-
RewritePath=/app-api/infra/v
2/api-docs, /v2
/api-docs
-
RewritePath=/app-api/infra/v
3/api-docs, /v3
/api-docs
-
id
:
bpm-admin-api
# 路由的编号
uri
:
grayLb://bpm-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/admin-api/bpm/**
filters
:
-
RewritePath=/admin-api/bpm/v
2/api-docs, /v2
/api-docs
-
RewritePath=/admin-api/bpm/v
3/api-docs, /v3
/api-docs
-
id
:
report-admin-api
# 路由的编号
uri
:
grayLb://report-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-
Path=/admin-api/report/**
filters
:
-
RewritePath=/admin-api/report/v
2/api-docs, /v2
/api-docs
-
RewritePath=/admin-api/report/v
3/api-docs, /v3
/api-docs
-
id
:
report-jmreport
# 路由的编号(积木报表)
uri
:
grayLb://report-server
predicates
:
# 断言,作为路由的匹配条件,对应 RouteDefinition 数组
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论