摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-route-to-request/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Spring-Cloud-Gateway 2.0.X M4


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 概述

本文主要分享 RouteToRequestUrlFilter 的代码实现

RouteToRequestUrlFilter 根据匹配的 Route ,计算请求的地址。注意,这里的地址指的是 URL ,而不是 URI

😈 RouteToRequestUrlFilter 的代码十分少,所以这会是一篇简单的文章。


推荐 Spring Cloud 书籍

2. RouteToRequestUrlFilter

org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter ,代码如下 :

1: public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
2:
3: private static final Log log = LogFactory.getLog(RouteToRequestUrlFilter.class);
4: public static final int ROUTE_TO_URL_FILTER_ORDER = 10000;
5:
6: @Override
7: public int getOrder() {
8: return ROUTE_TO_URL_FILTER_ORDER;
9: }
10:
11: @Override
12: public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
13: // 获得 Route
14: Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
15: if (route == null) {
16: return chain.filter(exchange);
17: }
18: log.trace("RouteToRequestUrlFilter start");
19: // 拼接 requestUrl
20: URI requestUrl = UriComponentsBuilder.fromHttpRequest(exchange.getRequest())
21: .uri(route.getUri())
22: .build(true) // encoded=true
23: .toUri();
24: // 设置 requestUrl 到 GATEWAY_REQUEST_URL_ATTR {@link RewritePathGatewayFilterFactory}
25: exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
26: // 提交过滤器链继续过滤
27: return chain.filter(exchange);
28: }
29:
30: }

Route.uriRequest.urirequestUrl
http://bin.org:80http://127.0.0.1:8080/test/segmenthttp://httpbin.org:80/123
http://bin.org:80/123http://127.0.0.1:8080/test/segmenthttp://httpbin.org:80/test/segment
  • 为什么会导致覆盖的情况呢 ?答案在 UriComponentsBuilder#uri(URI) 方法,代码如下 :

      1: public UriComponentsBuilder uri(URI uri) {
      2: 	Assert.notNull(uri, "URI must not be null");
      3: 	this.scheme = uri.getScheme();
      4: 	if (uri.isOpaque()) {
      5: 		this.ssp = uri.getRawSchemeSpecificPart();
      6: 		resetHierarchicalComponents();
      7: 	}
      8: 	else {
      9: 		if (uri.getRawUserInfo() != null) {
     10: 			this.userInfo = uri.getRawUserInfo();
     11: 		}
     12: 		if (uri.getHost() != null) {
     13: 			this.host = uri.getHost();
     14: 		}
     15: 		if (uri.getPort() != -1) {
     16: 			this.port = String.valueOf(uri.getPort());
     17: 		}
     18: 		if (StringUtils.hasLength(uri.getRawPath())) {
     19: 			this.pathBuilder = new CompositePathComponentBuilder();
     20: 			this.pathBuilder.addPath(uri.getRawPath());
     21: 		}
     22: 		if (StringUtils.hasLength(uri.getRawQuery())) {
     23: 			this.queryParams.clear();
     24: 			query(uri.getRawQuery());
     25: 		}
     26: 		resetSchemeSpecificPart();
     27: 	}
     28: 	if (uri.getRawFragment() != null) {
     29: 		this.fragment = uri.getRawFragment();
     30: 	}
     31: 	return this;
     32: }
    
    • 第 18 至 21 行 :当 uri 参数有 Path 时,新建一个 CompositePathComponentBuilder ,因此原有的 this.pathBuilder覆盖了。
  • 第 25 行 :设置 requestUrlGATEWAY_REQUEST_URL_ATTR 。后面 Routing 相关的 GatewayFilter 会通过该属性,发起请求。

  • 第 27 行 :提交过滤器链继续过滤。注意,这里不需要创建的 ServerWebExchange 。

666. 彩蛋

知识星球

😈 硬生生把这个文章丰富了下。人生如戏,全靠套路。

胖友,分享一波朋友圈可好!

文章目录
  1. 1. 1. 概述
  2. 2. 2. RouteToRequestUrlFilter
  3. 3. 666. 彩蛋