本文主要研究一下spring cloud的RequestHeaderToRequestUriGatewayFilterhtml
spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.javajava
@Configuration @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true) @EnableConfigurationProperties @AutoConfigureBefore(HttpHandlerAutoConfiguration.class) @AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class}) @ConditionalOnClass(DispatcherHandler.class) public class GatewayAutoConfiguration { //...... @Bean public RequestHeaderToRequestUriGatewayFilterFactory requestHeaderToRequestUriGatewayFilterFactory() { return new RequestHeaderToRequestUriGatewayFilterFactory(); } //...... }
spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/RequestHeaderToRequestUriGatewayFilterFactory.javaspring
/** * This filter changes the request uri by a request header * * @author Toshiaki Maki */ public class RequestHeaderToRequestUriGatewayFilterFactory extends AbstractChangeRequestUriGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> { private final Logger log = LoggerFactory .getLogger(RequestHeaderToRequestUriGatewayFilterFactory.class); public RequestHeaderToRequestUriGatewayFilterFactory() { super(NameConfig.class); } @Override public List<String> shortcutFieldOrder() { return Arrays.asList(NAME_KEY); } @Override protected Optional<URI> determineRequestUri(ServerWebExchange exchange, NameConfig config) { String requestUrl = exchange.getRequest().getHeaders().getFirst(config.getName()); return Optional.ofNullable(requestUrl).map(url -> { try { return new URL(url).toURI(); } catch (MalformedURLException | URISyntaxException e) { log.info("Request url is invalid : url={}, error={}", requestUrl, e.getMessage()); return null; } }); } }
spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/AbstractChangeRequestUriGatewayFilterFactory.javaapp
/** * This filter changes the request uri by * {@link #determineRequestUri(ServerWebExchange, T)} logic. * * @author Toshiaki Maki */ public abstract class AbstractChangeRequestUriGatewayFilterFactory<T> extends AbstractGatewayFilterFactory<T> { private final int order; public AbstractChangeRequestUriGatewayFilterFactory(Class<T> clazz, int order) { super(clazz); this.order = order; } public AbstractChangeRequestUriGatewayFilterFactory(Class<T> clazz) { this(clazz, RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER + 1); } protected abstract Optional<URI> determineRequestUri(ServerWebExchange exchange, T config); public GatewayFilter apply(T config) { return new OrderedGatewayFilter((exchange, chain) -> { Optional<URI> uri = this.determineRequestUri(exchange, config); uri.ifPresent(u -> { Map<String, Object> attributes = exchange.getAttributes(); attributes.put(GATEWAY_REQUEST_URL_ATTR, u); }); return chain.filter(exchange); }, this.order); } }
這裏就是取出url,設置GATEWAY_REQUEST_URL_ATTR,而後GlobalFilter裏頭會根據這個屬性取出url出來使用curl
spring: cloud: gateway: enabled: true discovery: locator: enabled: true routes: - id: demo uri: http://wwww.baidu.com predicates: - Path=/baidu/** filters: - RequestHeaderToRequestUri=X-New-Url
好比這裏設置了根據X-New-Url來進行新的url路由,那麼執行下面這段代碼,則請求/baidu的則會轉向請求163的ide
curl -i -H "X-New-Url: http://news.163.com" localhost:10000/baidu
RequestHeaderToRequestUriGatewayFilter實現的功能就是根據配置文件指定的header來讀取新的路由的url。比較強大,能夠用在灰度、生產定位問題等場景上。this