内容简介:网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8) 之 WebClientHttpRoutingFilter
摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-web-client-http-routing/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Spring-Cloud-Gateway 2.0.X M4
- 1. 概述
- 2. 环境配置
- 3. WebClientHttpRoutingFilter
- 4. WebClientWriteResponseFilter
- 5. 和 NettyRoutingFilter 对比
- 666. 彩蛋
关注 微信公众号:【芋道源码】 有福利:
- RocketMQ / MyCAT / Sharding-JDBC 所有 源码分析文章列表
- RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
- 您对于源码的疑问每条留言 都 将得到 认真 回复。 甚至不知道如何读源码也可以请教噢 。
- 新的 源码解析文章 实时 收到通知。 每周更新一篇左右 。
- 认真的 源码交流微信群。
1. 概述
本文主要分享 WebClientHttpRoutingFilter 的代码实现 。
WebClientHttpRoutingFilter ,Http 路由 网关过滤器。其根据 http://
或 https://
前缀( Scheme )过滤处理,使用基于 org.springframework.cloud.gateway.filter.WebClient
实现的 HttpClient 请求后端 Http 服务。
WebClientWriteResponseFilter ,与 WebClientHttpRoutingFilter 成对使用 的网关过滤器。其将 WebClientWriteResponseFilter 请求后端 Http 服务的 响应 写回客户端。
大体流程如下 :
2. 环境配置
目前 WebClientHttpRoutingFilter / WebClientWriteResponseFilter 处于 实验 阶段,建议等正式发布在使用。
OK,下面我们来看看怎么配置环境。
第一步,在 NettyConfiguration 注释掉 #routingFilter(...)
和 #nettyWriteResponseFilter()
两个 Bean 方法。
第二步,在 GatewayAutoConfiguration 打开 #webClientHttpRoutingFilter()
和 #webClientWriteResponseFilter()
两个 Bean 方法。
第三步,配置完成,启动 Spring Cloud Gateway 。
3. WebClientHttpRoutingFilter
org.springframework.cloud.gateway.filter.WebClientHttpRoutingFilter
,Http 路由 网关过滤器。
构造方法,代码如下 :
public class WebClientHttpRoutingFilter implements GlobalFilter, Ordered{ private final WebClient webClient; public WebClientHttpRoutingFilter(WebClient webClient){ this.webClient = webClient; } }
-
webClient
属性,默认情况下,使用org.springframework.web.reactive.function.client.DefaultWebClient
实现类。通过该属性, 请求后端的 Http 服务 。
#getOrder()
方法,代码如下 :
@Override public int getOrder(){ return Ordered.LOWEST_PRECEDENCE; }
- 返回顺序为
Integer.MAX_VALUE
。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.1) 之 GatewayFilter 一览》「3. GlobalFilter」 ,我们列举了所有 GlobalFilter 的顺序。
#filter(ServerWebExchange, GatewayFilterChain)
方法,代码如下 :
1: @Override 2: public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){ 3: // 获得 requestUrl 4: URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); 5: 6: // 判断是否能够处理 7: String scheme = requestUrl.getScheme(); 8: if (isAlreadyRouted(exchange) || (!scheme.equals("http") && !scheme.equals("https"))) { 9: return chain.filter(exchange); 10: } 11: 12: // 设置已经路由 13: setAlreadyRouted(exchange); 14: 15: ServerHttpRequest request = exchange.getRequest(); 16: 17: //TODO: support forms 18: // Request Method 19: HttpMethod method = request.getMethod(); 20: 21: // Request 22: RequestBodySpec bodySpec = this.webClient.method(method) 23: .uri(requestUrl) 24: .headers(httpHeaders -> { 25: httpHeaders.addAll(request.getHeaders()); 26: httpHeaders.remove(HttpHeaders.HOST); 27: }); 28: 29: // Request Body 30: RequestHeadersSpec<?> headersSpec; 31: if (requiresBody(method)) { 32: headersSpec = bodySpec.body(BodyInserters.fromDataBuffers(request.getBody())); 33: } else { 34: headersSpec = bodySpec; 35: } 36: 37: return headersSpec.exchange() 38: // .log("webClient route") 39: .flatMap(res -> { 40: ServerHttpResponse response = exchange.getResponse(); 41: 42: // Response Header 43: response.getHeaders().putAll(res.headers().asHttpHeaders()); 44: 45: // Response Status 46: response.setStatusCode(res.statusCode()); 47: 48: // 设置 Response 到 CLIENT_RESPONSE_ATTR 49: // Defer committing the response until all route filters have run 50: // Put client response as ServerWebExchange attribute and write response later NettyWriteResponseFilter 51: exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res); 52: return chain.filter(exchange); 53: }); 54: }
- 第 4 行 :获得
requestUrl
。 -
第 7 至 10 行 :判断 ForwardRoutingFilter 是否能够处理该请求,需要满足两个条件 :
-
http://
或者https://
前缀( Scheme ) 。 -
调用
ServerWebExchangeUtils#isAlreadyRouted(ServerWebExchange)
方法,判断该请求暂未被其他 Routing 网关处理。代码如下 :public static boolean isAlreadyRouted(ServerWebExchange exchange){ return exchange.getAttributeOrDefault(GATEWAY_ALREADY_ROUTED_ATTR, false); }
-
-
第 13 行 :设置该请求已经被处理。代码如下 :
public static void setAlreadyRouted(ServerWebExchange exchange){ exchange.getAttributes().put(GATEWAY_ALREADY_ROUTED_ATTR, true); }
-
第 17 行 :TODO 【3025】 目前暂不支持 forms 参数
- 第 22 至 35 行 : 创建 向后端服务的请求。
- 第 22 行 :设置 Method 属性。
- 第 24 至 27 行 :设置 Header 属性。
- 第 30 至 35 行 :设置 Body 属性。
- 第 37 行 : 发起 向后端服务的请求。
- 第 40 至 53 行 : 处理 返回自后端服务的相应。
- 第 43 行 :设置
response
的 Header 属性。 - 第 46 行 :设置
response
的 Status 属性。 - 第 51 行 :设置
res
到CLIENT_RESPONSE_ATTR
。后续 WebClientWriteResponseFilter 将响应 写回 给客户端。 - 第 52 行 :提交过滤器链继续过滤。
- 第 43 行 :设置
4. WebClientWriteResponseFilter
org.springframework.cloud.gateway.filter.WebClientWriteResponseFilter
,Http 回写 响应 网关过滤器。
#getOrder()
方法,代码如下 :
public static final int WRITE_RESPONSE_FILTER_ORDER = -1; @Override public int getOrder(){ return WRITE_RESPONSE_FILTER_ORDER; }
- 返回顺序为
-1
。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.1) 之 GatewayFilter 一览》「3. GlobalFilter」 ,我们列举了所有 GlobalFilter 的顺序。
#filter(ServerWebExchange, GatewayFilterChain)
方法,代码如下 :
1: @Override 2: public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){ 3: // NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added 4: // until the WebHandler is run 5: return chain.filter(exchange).then(Mono.defer(() -> { 6: // 获得 Response 7: ClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR); 8: if (clientResponse == null) { 9: return Mono.empty(); 10: } 11: log.trace("WebClientWriteResponseFilter start"); 12: ServerHttpResponse response = exchange.getResponse(); 13: 14: return response.writeWith(clientResponse.body(BodyExtractors.toDataBuffers())).log("webClient response"); 15: })); 16: }
- 第 5 行 :调用
#then(Mono)
方法,实现 After Filter 逻辑。 - 第 7 至 11 行 :从
CLIENT_RESPONSE_ATTR
中,获得 ClientResponse 。 - 第 14 行 :将 ClientResponse 写回给客户端。
5. 和 NettyRoutingFilter 对比
在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 中,我们知道 NettyRoutingFilter / NettyWriteResponseFilter 和 WebClientHttpRoutingFilter / WebClientHttpRoutingFilter 实现 一样 的功能。
那么为什么要再实现一次呢?
TODO 【3001】
666. 彩蛋
呼呼,主要的过滤器已经写完,后面熔断、限流过滤器的实现。
胖友,分享一波朋友圈可好!
以上所述就是小编给大家介绍的《网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8) 之 WebClientHttpRoutingFilter》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Spring Cloud(七):服务网关zuul过滤器
- 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.3) 之 RouteToRequestUrlFilter
- 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.5) 之 ForwardRoutingFilter
- 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.6) 之 WebSocketRoutingFilter
- 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter
- 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to the Analysis of Algorithms
Robert Sedgewick、Philippe Flajolet / Addison-Wesley Professional / 1995-12-10 / CAD 67.99
This book is a thorough overview of the primary techniques and models used in the mathematical analysis of algorithms. The first half of the book draws upon classical mathematical material from discre......一起来看看 《An Introduction to the Analysis of Algorithms》 这本书的介绍吧!