SwaggerProvider.java 3.3 KB
Newer Older
liuzhixiong's avatar
liuzhixiong committed
1 2
package cn.iocoder.yudao.gateway.swagger;

3 4 5
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
liuzhixiong's avatar
liuzhixiong committed
6
import org.springframework.cloud.gateway.config.GatewayProperties;
7 8
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
liuzhixiong's avatar
liuzhixiong committed
9 10 11 12 13 14
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;

15 16 17 18 19 20
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

liuzhixiong's avatar
liuzhixiong committed
21
/**
22 23
 * Swagger 资源的 Provider 实现类
 *
liuzhixiong's avatar
liuzhixiong committed
24
 * @author zxliu
25
 * @date 2022-10-25 11:23
liuzhixiong's avatar
liuzhixiong committed
26 27 28
 */
@Component
@Primary
29
@Slf4j
liuzhixiong's avatar
liuzhixiong committed
30 31
public class SwaggerProvider implements SwaggerResourcesProvider {

32 33
    @Resource
    private GatewayProperties gatewayProperties;
liuzhixiong's avatar
liuzhixiong committed
34

35 36 37 38 39
    /**
     * 获得 SwaggerResource 列表
     *
     * @return SwaggerResource 列表
     */
liuzhixiong's avatar
liuzhixiong committed
40 41
    @Override
    public List<SwaggerResource> get() {
42
        // 将 RouteDefinition 转换成 SwaggerResource
liuzhixiong's avatar
liuzhixiong committed
43
        List<SwaggerResource> resources = new ArrayList<>();
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
        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;
            }
liuzhixiong's avatar
liuzhixiong committed
60

61 62 63
            // 重要:构建最终的 SwaggerResource 对象
            resources.add(buildSwaggerResource(serviceName, path));
        });
liuzhixiong's avatar
liuzhixiong committed
64 65 66
        return resources;
    }

67
    private SwaggerResource buildSwaggerResource(String name, String location) {
liuzhixiong's avatar
liuzhixiong committed
68 69 70 71 72 73 74
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }

75 76 77 78 79 80 81 82 83 84 85 86 87 88
    /**
     * 获得路由的 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(),
xingyu4j's avatar
xingyu4j committed
89
                predicateDefinition -> "Path".equals(predicateDefinition.getName()));
90 91 92 93 94 95 96 97 98 99 100 101
        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");
    }

liuzhixiong's avatar
liuzhixiong committed
102
}