Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.3) 之 RouteToRequestUrlFilter

x33g5p2x  于2021-12-20 转载在 其他  
字(2.7k)|赞(0)|评价(0)|浏览(277)

1. 概述

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

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

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

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 行 :设置 requestUrl 到 GATEWAY_REQUEST_URL_ATTR 。后面 Routing 相关的 GatewayFilter 会通过该属性,发起请求。
  • 第 27 行 :提交过滤器链继续过滤。注意,这里不需要创建的 ServerWebExchange 。

相关文章