⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 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. 认真的源码交流微信群。

阅读源码最好的方式,是使用 IDEA 进行调试 Spring Cloud Gateway 源码,不然会一脸懵逼。

胖友可以点击「芋道源码」扫码关注,回复 git019 关键字
获得艿艿添加了中文注释的 Spring Cloud Gateway 源码地址。

阅读源码很孤单,加入源码交流群,一起坚持!

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.uri Request.uri requestUrl
http://bin.org:80 http://127.0.0.1:8080/test/segment http://httpbin.org:80/123
http://bin.org:80/123 http://127.0.0.1:8080/test/segment http://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. 彩蛋