实现Gateway网关统一Swagger入口

话不多说,,,先解释一波。

Swagger是现在前后端都比较喜欢的一个接口文档插件,服务端同学简单的编辑就可以给前端同学呈现出可以直接调试的接口文档,可以说是非常的6。现在微服务都是通过网关转发到各个服务上的,那么Swagger理所当然的也应该由网关代理,这篇文章主要就是记录一下由Gateway代理Swagger的方法。

gateway:

spring:
  cloud:
    gateway:
      routes: #数组形式
        - id: product-service  #路由唯一标识
          uri: lb://XXX_XXX_server  #从nocas进行转发,所以这个名字是服务在nocas内注册的名字
          order: 1 #优先级,数字越小优先级越高
          predicates: #配置转发路径,前端访问路径统一加上XXX-server,网关判断转发对应的服务
            - Path=/XXX-server/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1  #去掉第一层前缀,转发给后续的路径
package com.home.config;


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 java.util.Optional;

/**
 * 网关转发swagger请求
 */
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;
    @Autowired(required = false)
    private UiConfiguration uiConfiguration;
    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }

    @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));
    }

    @GetMapping("")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

package com.home.config;


import lombok.AllArgsConstructor;
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.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {

    public static final String API_URI = "/v3/api-docs";

    private final RouteLocator routeLocator;

    private final GatewayProperties gatewayProperties;


    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        //取出gateway的route
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        //结合配置的route-路径(Path),和route过滤,只获取有效的route节点
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                        .replace("/**", API_URI)))));
        return resources;
    }
    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }
}

微服务:

package com.home.exception;

import com.home.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import springfox.documentation.spring.web.json.Json;

import java.util.*;

/**
 * 重新封装swagger返回信息(需要网关代理的项目都需要重新封装,对单机请求没有影响)
 */
@Slf4j
@ControllerAdvice(basePackages = "springfox.documentation.oas.web")
public class SwaggerHandle implements ResponseBodyAdvice<Object> {

    @Value("${spring.application.name}")
    private String applictionName;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object object, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (object == null) {
            return null;
        }
        //获取请求头
        HttpHeaders headers = serverHttpRequest.getHeaders();
        Set<String> strings = headers.keySet();
        //判断请求是否经过网关转发
        boolean isForwarded = strings.contains("forwarded");
        if (isForwarded) {
            String x_forwarded_for = headers.get("x-forwarded-for").get(0);
            String x_forwarded_proto = headers.get("x-forwarded-proto").get(0);
            String x_forwarded_prefix = headers.get("x-forwarded-prefix").get(0);
            String x_forwarded_port = headers.get("x-forwarded-port").get(0);
            String x_forwarded_host = headers.get("x-forwarded-host").get(0);
            //重新组装servers(总感觉方法有点low。。。)
            Json jsons = (Json) object;
            String value = jsons.value();
            Map map = JsonUtil.toObject(value, Map.class);
            List<Map<String, String>> servers = new ArrayList<>();
            Map<String, String> server = new HashMap<>();
            server.put("url", x_forwarded_proto + "://" + x_forwarded_host + x_forwarded_prefix);
            server.put("description", applictionName);
            servers.add(server);
            map.put("servers", servers);
            return new Json(JsonUtil.toJson(map));
        } else {
            return object;
        }
    }
}

这里面用到的工具类:JsonUtil

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: gateway网关)和swagger3可以结合使用,以便显示和测试API的好处。Swagger是一种API规范,使API文档易于理解和使用。网关将客户端请求发送到API,并将API响应返回给客户端,可以通过swagger UI进行预览和测试。 ### 回答2: Gateway网关是一个负责接入各种服务的组件,在系统架构中扮演着重要的角色。它可以对入口请求进行统一处理,如鉴权、路由、流量控制等,并将请求转发到具体的服务上。 Swagger3是一种流行的API文档生成框架,旨在帮助开发人员更好地理解和使用API。 在Gateway网关中聚合Swagger3,可以实现以下功能: 1. 统一的API文档:在Gateway网关中集成Swagger3,可以方便地生成API文档,并在统一的位置对外暴露。这样不仅可以减少开发人员重复编写文档的工作量,而且可以提高文档的可读性和可维护性。 2. 经过授权的API调用:Gateway网关可以通过集成Swagger3的鉴权功能,将用户授权和API调用联系起来。这意味着只有经过授权的用户才能调用特定的API,从而提高了系统的安全性。 3. 统一的API管理:通过Gateway网关,可以将不同的API集成进来,并在同一个位置进行管理和监控。这样可以减少API管理过程中的复杂度,提高管理效率。 4. 支持多种协议:Gateway网关可以支持多种协议,如HTTP、WebSocket、TCP和UDP等。通过聚合Swagger3,可以更好地支持RESTful风格的API,并对其他协议提供更好的支持。 综上所述,Gateway网关中聚合Swagger3可以提高系统的可维护性和可扩展性,同时也可以使API的管理更加方便和高效。此外,它还可以提高系统的安全性,更好地支持RESTful风格的API,并供其他协议提供更好的支持。 ### 回答3: Gateway网关被广泛应用于微服务架构,其作为微服务系统的入口,扮演着负载均衡、路由转发、安全验证、限流熔断等重要角色。Swagger是一种用于描述和共享RESTful API的工具,Swagger可以帮助开发人员快速了解其使用API的方式,节省开发时间。 随着Swagger的不断发展,Swagger 3.0版本已经推出,并且在一定程度上解决了Swagger 2.0存在的问题。使用Swagger 3.0可以更加方便地描述和调试API,并且可以支持多种编程语言。与此同时,Gateway网关Swagger 3.0的整合也为企业多个微服务之间的信息传递带来了更加便利的方式。Gateway网关可以将多个微服务的接口进行聚合,进而组成一个统一的API接口,而Swagger 3.0的描述规范可以使Gateway网关更加精准地描述这些API接口的使用方式和参数信息,从而使API的使用者能够更加便捷地了解API的使用方式,提高了开发效率。 通过Gateway网关中聚合Swagger 3.0,企业可以将多个微服务API进行整合,组成一个更加高效的整体API接口,并且可以减少开发人员的代码开发量。同时,这种集成方式也可以使API的使用者更加方便地了解API的基本信息,减少了可能出现的错误和不必要的麻烦。因此,Gateway网关中聚合Swagger 3.0是非常重要的,对企业提升API管理能力、提高开发效率和优化用户体验有着巨大的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在写bug的路上越走越远

谢谢老板,老板发大财

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值