• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Spring Cloud Gateway 网关拦截转发

武飞扬头像
一日々漫城*
帮助1

1.application.yml配置

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: remoteaddr_route
  6.  
    uri: http://localhost:8080
  7.  
    predicates:
  8.  
    - Path=/test
  9.  
    filters:
  10.  
    - RewritePath=/test, /add
  11.  
    - Test

参数解析:

predicates:当满足predicates下的条件时,即path路径为/test时网关生效。

uri:跳转到uri(注意:此处为uri不是url)。

filters:filters 下的RewritePath会将路径重定义将/test换为/add。若不加此处就会将path所带路径自动拼接到uri后面。

最后一行的- Test 是文件名,下面会写到

2.网关实现

网关的主要实现由Filter,Mono,GatewayFilterFactory三部分组成。

解析:

GatewayFilterFactory:上面的-Test的文件名就是此处的名称应为TestGatewayFilterFactory,网关匹配时会自动忽略后面的GatewayFilterFactory,从而通过Test找到TestGatewayFilterFactory。

  1.  
    @Component
  2.  
    @Slf4j
  3.  
    @Lazy
  4.  
    public class TestGatewayFilterFactory extends AbstractGatewayFilterFactory {
  5.  
    @Autowired
  6.  
    TestFilter TestFilter;
  7.  
     
  8.  
    @Override
  9.  
    public GatewayFilter apply(Object config) {
  10.  
    return TestFilter;
  11.  
    }
  12.  
    }

Filter:相当于一个中间层

  1.  
    @Component
  2.  
    public class TestFilter implements GatewayFilter, Ordered {
  3.  
    @Autowired
  4.  
    TestMono TestMono;
  5.  
     
  6.  
    @Override
  7.  
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  8.  
    return TestMono.testMono(exchange, chain);
  9.  
    }
  10.  
     
  11.  
    @Override
  12.  
    public int getOrder() {
  13.  
    return -2;
  14.  
    }
  15.  
    }
学新通

Mono:主要的逻辑实现层

主要实现由testMono来协调,网关转发的请求的解析在此方法内实现,若有解密需求在此方法内添加方法即可。

requestDecorator:此方法用于请求的转换,代码中实现的是将post请求转为get。

urlEncodeUTF8:在此代码的实现中用于解析post请求的参数将其拼接到get请求中。

responseDecorator:网关处理完毕后返回的结果将在这里包装后输出,若有加密在此方法内执行。

  1.  
    @Component
  2.  
    @Slf4j
  3.  
    public class TestMono {
  4.  
     
  5.  
    //主方法
  6.  
    public Mono<Void> testMono(ServerWebExchange exchange, GatewayFilterChain chain) {
  7.  
    ServerHttpRequest request = exchange.getRequest();
  8.  
    ServerHttpResponse response = exchange.getResponse();
  9.  
    return DataBufferUtils.join(request.getBody())
  10.  
    .flatMap(dataBuffer -> {
  11.  
    DataBufferUtils.retain(dataBuffer);
  12.  
    byte[] bytes = new byte[dataBuffer.readableByteCount()];
  13.  
    dataBuffer.read(bytes);
  14.  
    //释放掉内存
  15.  
    DataBufferUtils.release(dataBuffer);
  16.  
    String body = new String(bytes, StandardCharsets.UTF_8);
  17.  
    URI url = request.getURI();
  18.  
    log.info("url: {}", url);
  19.  
    JSONObject bodyJson = JSON.parseObject(body);
  20.  
    JSONObject innerBody = bodyJson.getJSONObject("BODY");
  21.  
     
  22.  
    return chain.filter(exchange.mutate().request(requestDecorator(request, innerBody)).response(responseDecorator(response)).build());
  23.  
    });
  24.  
    }
  25.  
     
  26.  
    //将post请求转换成get(若是get可连同下面的方法省略)
  27.  
    private static ServerHttpRequestDecorator requestDecorator(ServerHttpRequest request, JSONObject body) {
  28.  
    return new ServerHttpRequestDecorator(request) {
  29.  
    // 重新设置http method
  30.  
    @Override
  31.  
    public HttpMethod getMethod() {
  32.  
    return HttpMethod.GET;
  33.  
    }
  34.  
     
  35.  
    @Override
  36.  
    public String getMethodValue() {
  37.  
    return "GET";
  38.  
    }
  39.  
     
  40.  
    // 转换请求参数
  41.  
    @Override
  42.  
    public URI getURI() {
  43.  
    String params = urlEncodeUTF8(body);
  44.  
    return URI.create(request.getURI() "?" params);
  45.  
    }
  46.  
    };
  47.  
    }
  48.  
     
  49.  
    /**
  50.  
    * 转换urlparam
  51.  
    *(post请求忽略)
  52.  
    * @param jsonObject
  53.  
    * @return
  54.  
    */
  55.  
    private static String urlEncodeUTF8(JSONObject jsonObject) {
  56.  
    StringBuilder sb = new StringBuilder();
  57.  
    for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
  58.  
    if (sb.length() > 0) {
  59.  
    sb.append("&");
  60.  
    }
  61.  
    sb.append(String.format("%s=%s",
  62.  
    entry.getKey(),
  63.  
    entry.getValue()
  64.  
    ));
  65.  
    }
  66.  
    log.info("format param: {}", sb);
  67.  
    return sb.toString();
  68.  
    }
  69.  
     
  70.  
     
  71.  
    //网关转出
  72.  
    private ServerHttpResponseDecorator responseDecorator
  73.  
    (ServerHttpResponse response) {
  74.  
    return new ServerHttpResponseDecorator(response) {
  75.  
     
  76.  
    @Override
  77.  
    public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
  78.  
    if (body instanceof Flux) {
  79.  
    Flux<? extends DataBuffer> flux = Flux.from(body);
  80.  
    return super.writeWith(flux.buffer().map(dataBuffers -> {
  81.  
    DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
  82.  
    StringBuilder sb = new StringBuilder("");
  83.  
    DataBuffer join = dataBufferFactory.join(dataBuffers);
  84.  
    byte[] bytes = new byte[join.readableByteCount()];
  85.  
    join.read(bytes);
  86.  
    DataBufferUtils.release(join);
  87.  
    String s = new String(bytes, StandardCharsets.UTF_8);
  88.  
    sb.append(s);
  89.  
    //去掉字符串最外层的[]
  90.  
    //sb.deleteCharAt(0).deleteCharAt(sb.length() - 1);`
  91.  
    // 构造返回报文
  92.  
    JSONObject jsonBody = JSON.parseObject(sb.toString(), JSONObject.class, Feature.OrderedField);
  93.  
     
  94.  
     
  95.  
    String content = JSON.toJSONString(jsonBody, SerializerFeature.WRITE_MAP_NULL_FEATURES, SerializerFeature.QuoteFieldNames, SerializerFeature.PrettyFormat);
  96.  
    byte[] contentByte = content.getBytes();
  97.  
    // 重置content-length
  98.  
    response.getHeaders().setContentLength(contentByte.length);
  99.  
    return response.bufferFactory().wrap(contentByte);
  100.  
    }));
  101.  
    }
  102.  
    return super.writeWith(body);
  103.  
    }
  104.  
    };
  105.  
    }
  106.  
     
  107.  
     
  108.  
    }
学新通

Spring cloud gateway学习地址:Spring Cloud Gateway 2.1.0 中文官网文档 - 云 社区 - 腾讯云

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfjaefh
系列文章
更多 icon
同类精品
更多 icon
继续加载