黑马程序员技术交流社区

标题: 【上海校区网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8... [打印本页]

作者: 不二晨    时间: 2018-7-19 09:22
标题: 【上海校区网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8...
1. 概述
本文主要分享 WebClientHttpRoutingFilter 的代码实现。
WebClientHttpRoutingFilter ,Http 路由网关过滤器。其根据 http:// 或 https:// 前缀( Scheme )过滤处理,使用基于 org.springframework.cloud.gateway.filter.WebClient 实现的 HttpClient 请求后端 Http 服务。
WebClientWriteResponseFilter ,与 WebClientHttpRoutingFilter 成对使用的网关过滤器。其将 WebClientWriteResponseFilter 请求后端 Http 服务的响应写回客户端。
大体流程如下 :

推荐 Spring Cloud 书籍:
推荐 Spring Cloud 视频:
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;        }}
#getOrder() 方法,代码如下 :
@Overridepublic int getOrder() {    return Ordered.LOWEST_PRECEDENCE;}
#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 forms18:         // Request Method19:         HttpMethod method = request.getMethod();20: 21:         // Request22:         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 Body30:         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 Header43:                                 response.getHeaders().putAll(res.headers().asHttpHeaders());44: 45:                                 // Response Status46:                                 response.setStatusCode(res.statusCode());47: 48:                                 // 设置 Response 到 CLIENT_RESPONSE_ATTR49:                                 // Defer committing the response until all route filters have run50:                                 // Put client response as ServerWebExchange attribute and write response later NettyWriteResponseFilter51:                                 exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);52:                                 return chain.filter(exchange);53:                         });54: }4. WebClientWriteResponseFilter
org.springframework.cloud.gateway.filter.WebClientWriteResponseFilter ,Http 回写响应网关过滤器。
#getOrder() 方法,代码如下 :
public static final int WRITE_RESPONSE_FILTER_ORDER = -1;    @Overridepublic int getOrder() {    return WRITE_RESPONSE_FILTER_ORDER;}
#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. 和 NettyRoutingFilter 对比
《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 中,我们知道 NettyRoutingFilter / NettyWriteResponseFilter 和 WebClientHttpRoutingFilter / WebClientHttpRoutingFilter 实现一样的功能。
【转载】https://juejin.im/entry/5b4fb88251882519861c0bcd


作者: 不二晨    时间: 2018-7-19 10:58
优秀,奈斯
作者: 摩西摩西OvO    时间: 2018-7-19 14:25

作者: 吴琼老师    时间: 2018-7-19 16:40

作者: 摩西摩西OvO    时间: 2018-7-23 13:35

作者: 摩西摩西OvO    时间: 2018-7-26 09:19





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2