package org.springframework.cloud.gateway.handler;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
/**
* WebHandler that delegates to a chain of {@link GlobalFilter} instances and
* {@link GatewayFilterFactory} instances then to the target {@link WebHandler}.
*
* @author Rossen Stoyanchev
* @author Spencer Gibb
* @since 0.1
*/
public class FilteringWebHandler implements WebHandler {
protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);
private final List<GatewayFilter> globalFilters;
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this.globalFilters = loadFilters(globalFilters);
}
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream().map(filter -> {
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
return new OrderedGatewayFilter(gatewayFilter, order);
}
return gatewayFilter;
}).collect(Collectors.toList());
}
/*
* TODO: relocate @EventListener(RefreshRoutesEvent.class) void handleRefresh() {
* this.combinedFiltersForRoute.clear();
*/
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
List<GatewayFilter> gatewayFilters = route.getFilters();
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
// TODO: needed or cached?
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private final int index;
private final List<GatewayFilter> filters;
DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
this.index = 0;
}
private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
this.filters = parent.getFilters();
this.index = index;
}
public List<GatewayFilter> getFilters() {
return filters;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
this.index + 1);
return filter.filter(exchange, chain);
}
else {
return Mono.empty(); // complete
}
});
}
}
private static class GatewayFilterAdapter implements GatewayFilter {
private final GlobalFilter delegate;
GatewayFilterAdapter(GlobalFilter delegate) {
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
sb.append("delegate=").append(delegate);
sb.append('}');
return sb.toString();
}
}
}
Spring Cloud GateWay 源码解析实战 - FilteringWebHandler(更新ing)
原创公众号JavaEdge ©著作权
©著作权归作者所有:来自51CTO博客作者公众号JavaEdge的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:JVM源码实战 - 对象头
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Spring Cloud Alibaba - 27 Gateway源码解析
文章目录How it works入口源码流程How it workshttps://docs.spring.io/spring-cloud-gateway/docs/current/refer
spring cloud gateway spring Gateway源码 源码分析 -
浅谈Spring Cloud Gateway源码
浅谈Spring Cloud Gateway执行流程
spring cloud java 微服务 MVC Cloud -
【Spring Cloud实战】Spring Cloud GateWay服务网关
GateWayCloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的Zuul网关
spring cloud 微服务 java spring 非阻塞 -
网关 Spring-Cloud-Gateway 源码解析 —— 调试环境搭建
1. 依赖工具2. 源码拉取3. 运行示例
spring 微服务 maven ide java -
java接收小程序发送的protobuf消息
/接收数据,对ProtoBu数据进行反序列化,返回的是ChargingCmd对象,ChargingCmdProtobuf.ChargingCmd是我们定义的消息类型,//添加消息转换处理器,将WebSocketFrame消息转换为ProtoBuf二进制类型的消息。//处理二进制消息,protobuf消息以二进制形式传输的。//添加到list中,交给下一个handler处理。//发送数据,对ProtoBu数据进行序列化。//retain引用计数,防止释放。//发送数据,ProtoBu序列化。
#netty #protobuf #websocket HTTP .net
















