聊聊spring cloud的RequestHeaderToRequestUri

本文主要研究一下spring cloud的RequestHeaderToRequestUriGatewayFilterhtml

GatewayAutoConfiguration

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();
	}
    //......
}

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;
			}
		});
	}
}
  • 主要是繼承了AbstractChangeRequestUriGatewayFilterFactory
  • 這裏重寫了determineRequestUri方法,根據配置的header取出url

AbstractChangeRequestUriGatewayFilterFactory

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

doc

相關文章
相關標籤/搜索