文章26 | 阅读 10676 | 点赞0
本文主要分享 ForwardRoutingFilter 的代码实现。
RouteToRequestUrlFilter ,转发路由网关过滤器。其根据 forward://
前缀( Scheme )过滤处理,将请求转发到当前网关实例本地接口。
举个例子,配置 RouteDefinition 路由定义如下 :
spring:
application:
name: juejin-gateway
cloud:
gateway:
routes:
# =====================================
- id: forward_sample
uri: forward:///globalfilters
order: 10000
predicates:
- Path=/globalfilters
filters:
- PrefixPath=/application/gateway
我们假定网关端口为 8080
。
当请求 http://127.0.0.1:8080/globalfilters
接口,Spring Cloud Gateway 处理过程如下 :
匹配到路由 Route (id = forward_sample
) 。
配置的 PrefixPathGatewayFilterFactory 将请求改写成 http://127.0.0.1:8080/application/gateway/globalfilters
。
ForwardRoutingFilter 判断有 forward://
前缀( Scheme ),过滤处理,将请求转发给 DispatcherHandler 。
DispatcherHandler 匹配并转发到当前网关实例本地接口 application/gateway/globalfilters
。
为什么需要配置 PrefixPathGatewayFilterFactory ?需要通过 PrefixPathGatewayFilterFactory 将请求重写路径,以匹配本地 API ,否则 DispatcherHandler 转发会失败。
另外,RouteToRequestUrlFilter 是 Spring Cloud Gateway 实现的一种路由网关过滤器,目前还提供 WebsocketRoutingFilter / NettyRoutingFilter / WebClientHttpRoutingFilter 。
org.springframework.cloud.gateway.filter.ForwardRoutingFilter
,代码如下 :
1: public class ForwardRoutingFilter implements GlobalFilter, Ordered {
2:
3: private static final Log log = LogFactory.getLog(ForwardRoutingFilter.class);
4:
5: private final DispatcherHandler dispatcherHandler;
6:
7: public ForwardRoutingFilter(DispatcherHandler dispatcherHandler) {
8: this.dispatcherHandler = dispatcherHandler;
9: }
10:
11: @Override
12: public int getOrder() {
13: return Ordered.LOWEST_PRECEDENCE;
14: }
15:
16: @Override
17: public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
18: // 获得 requestUrl
19: URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
20:
21: // 判断是否能够处理
22: String scheme = requestUrl.getScheme();
23: if (isAlreadyRouted(exchange) || !scheme.equals("forward")) {
24: return chain.filter(exchange);
25: }
26:
27: // 设置已经路由
28: setAlreadyRouted(exchange);
29:
30: //TODO: translate url?
31:
32: if (log.isTraceEnabled()) {
33: log.trace("Forwarding to URI: "+requestUrl);
34: }
35:
36: // DispatcherHandler 匹配并转发到当前网关实例本地接口
37: return this.dispatcherHandler.handle(exchange);
38: }
39: }
实现 GlobalFilter 接口。
#getOrder()
方法,返回顺序为 Integer.MAX_VALUE
。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.1) 之 GatewayFilter 一览》「3. GlobalFilter」 ,我们列举了所有 GlobalFilter 的顺序。
第 19 行 :获得 requestUrl
。
第 22 至 25 行 :判断 ForwardRoutingFilter 是否能够处理该请求,需要满足两个条件 :
forward://
前缀( Scheme ) 。
调用 ServerWebExchangeUtils#isAlreadyRouted(ServerWebExchange)
方法,判断该请求暂未被其他 Routing 网关处理。代码如下 :
public static boolean isAlreadyRouted(ServerWebExchange exchange) {
return exchange.getAttributeOrDefault(GATEWAY_ALREADY_ROUTED_ATTR, false);
}
public static void setAlreadyRouted(ServerWebExchange exchange) {
exchange.getAttributes().put(GATEWAY_ALREADY_ROUTED_ATTR, true);
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_42073629/article/details/106934534
内容来源于网络,如有侵权,请联系作者删除!