springGateway聚合各服务Swagger进行统一管理

网关配置

  1. 引入swagger相关依赖
<!--swagger-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

这里不建议引入像swagger-bootstrap-ui的第三方ui,对swagger3注解的兼容性不大好(我试了)

  1. 添加SwaggerConfig
@Component
@Primary
public class SwaggerConfig implements SwaggerResourcesProvider {

    /**
     * swagger3默认的url后缀
     */
    private static final String SWAGGER2URL = "/v3/api-docs"; //要使用ui的话 改成v2 不然会出bug  比如有的地方 没有输入框

    /**
     * 网关路由
     */
    private final RouteLocator routeLocator;

    /**
     * 网关应用名称
     */
    @Value("${spring.application.name}")
    private String self;

    @Autowired
    public SwaggerConfig(RouteLocator routeLocator) {
        this.routeLocator = routeLocator;
    }

    /**
     * 对于gateway来说这块比较重要 让swagger能找到对应的服务
     *
     * @return
     */
    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routeHosts = new ArrayList<>();
        HashMap<String, String> apiMap = new HashMap();
        // 获取所有可用的host:serviceId
        routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
                .filter(route -> !self.equals(route.getUri().getHost()))
                .subscribe(route -> {
                    routeHosts.add(route.getUri().getHost());
                    // 分割网关配置的拦截路径 这里取第一个  /api/user, /api/chat
                    String routeApi = route.getPredicate().toString().split("\\[")[1].split("]")[0].split(",")[0].replace("/**","");
                    apiMap.put(route.getUri().getHost(),routeApi);
                });

        // 记录已经添加过的server
        Set<String> dealed = new HashSet<>();
        routeHosts.forEach(instance -> {
            // 拼接url
            String url = apiMap.get(instance) + SWAGGER2URL;
            if (!dealed.contains(url)) {
                dealed.add(url);
                SwaggerResource swaggerResource = new SwaggerResource();
                swaggerResource.setUrl(url);
                swaggerResource.setName(instance);
                resources.add(swaggerResource);
            }
        });
        return resources;
    }

}

里面的apiMap的key是服务名(chat-websocket),value是第一个拦截的路径匹配式(/api/chat)
在这里插入图片描述

微服务配置

  1. 导入依赖
<!--swagger-->
 <dependency>
     <groupId>io.springfox</groupId>
     <artifactId>springfox-boot-starter</artifactId>
     <version>3.0.0</version>
 </dependency>
  1. 添加SwaggerConfig
@Configuration
@EnableSwagger2
@EnableOpenApi
public class SwaggerConfig2 implements WebMvcConfigurer {

    //配置了Swagger的Docket的bean实例
    //enable是否启动swagger,如果为False则Swagger不能在浏览器访问
    @Bean
    public Docket docket() {

        // 设置全局响应状态码 (这里的类是我自定义的枚举类,可以删掉这段)
        List<Response> responseList = new ArrayList<>();
        for (StatusCode statusCode : StatusCode.values()) {
            String description = statusCode.getDescription();
            String code = statusCode.getCode().toString();
            responseList.add(new ResponseBuilder().code(code).description(description).build());
        }
        // 支持的通讯协议集合
        Set<String> set = new HashSet<>();
        set.add("https");
        set.add("http");

        return new Docket(
                DocumentationType.SWAGGER_2)
                .enable(true)//定义是否开启swagger,false为关闭,可以通过变量控制
                .apiInfo(apiInfo())//将api的元信息设置为包含在json ResourceListing响应中。
                .select()
                .apis(RequestHandlerSelectors.basePackage("work.xiaohong"))
                //paths()过滤什么路径
                .paths(PathSelectors.any())
                .build()
                .protocols(set)
                //下面这个设置就是在接口的path前加上api
                .pathMapping("/api")
                // 全局响应配置
                .globalResponses(HttpMethod.GET,responseList)
                .globalResponses(HttpMethod.DELETE,responseList)
                .globalResponses(HttpMethod.POST,responseList)
                .globalResponses(HttpMethod.PUT,responseList)
                .globalResponses(HttpMethod.PATCH,responseList)
                .globalResponses(HttpMethod.HEAD,responseList)
                .globalResponses(HttpMethod.OPTIONS,responseList)
                .globalResponses(HttpMethod.TRACE,responseList)
                .securitySchemes(securitySchemes())// 授权信息设置,必要的header token等认证信息
                .securityContexts(securityContexts());// 授权信息全局应用
    }


    //作者信息
    Contact contact = new Contact("小鸿","https://www.xiaohong.work","1990063814@qq.com");

    //配置Swagger 信息 = ApiInfo
    private ApiInfo apiInfo()
    {
        return new ApiInfo("用户微服务",
                "用户微服务用户Api文档",
                "1.0.0",
                "https://www.xiaohong.work",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<>());
    }

    /**
     * 设置授权信息
     */
    private List<SecurityScheme> securitySchemes()
    {
        List<ApiKey> result = new ArrayList<>();
        ApiKey apiKey = new ApiKey("xiaohong-token","身份令牌" ,"Header" );
        result.add(apiKey);
        return  Collections.singletonList(apiKey);
    }

    /**
     * 授权信息全局应用
     */
    private List<SecurityContext> securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        //这里第一个参数要对应上面创建的ApiKey的name值
                        .securityReferences(Collections.singletonList(new SecurityReference("xiaohong-token", new AuthorizationScope[]{new AuthorizationScope("global", "身份令牌")})))
                        .build()
        );
    }

}

在Docket里的一个pathMapping配置我这里配成/api是因为swagger被网关接手了后,那所有请求的请求地址都需要经过网关,我这有个习惯就是在经过网关前的路径都加了/api前缀,在网关处再过滤掉,如果没有或有其他习惯的,可以自己看着写

测试

网关访问 http://localhost:8001/swagger-ui/index.html

在这里插入图片描述
先来测试一个接口试试
在这里插入图片描述

在这里插入图片描述
可以看到,这个接口是需要提供token进行权限验证的,同时,这里的请求路径都是从网关的地址再凭借上我们自己加的/api,最后再拼接上接口的请求路径

那我们添加上token再试一遍
在这里插入图片描述
在这里插入图片描述
完成后这两把锁都锁上了,表示添加成功
如果没有都锁上,就要去看看配置文件里的两个名字是否没有匹配上了

再次测试
在这里插入图片描述
可以看到这次将我们输入的token带入了请求头中
我们使用调试工具看看
在这里插入图片描述
可以看到确实添加进去了
这里响应权限不足那是后端的处理逻辑
换一个有权限的账号token即可
这里我有不实验了
另一个服务我也不测了(写之前我已经测试过了,就不展示了)
饿了,吃饭去了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值