Talk about spring cloud’s RequestHeaderToRequestUriGatewayfilter

  springcloud

Order

This article mainly studies spring cloud’s RequestHeaderToRequestUriGatewayfilter.

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC2-sources.jar! /org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@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.java

/**
 * 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;
            }
        });
    }
}
  • Mainly inherited abstract changerequesturigatewayfilterfactory
  • The determineRequestUri method is rewritten here to fetch the url according to the configured header.

AbstractChangeRequestUriGatewayFilterFactory

spring-cloud-gateway-core-2.0.0.RC2-sources.jar! /org/springframework/cloud/gateway/filter/factory/AbstractChangeRequestUriGatewayFilterFactory.java

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

This is to retrieve the url, set GATEWAY_REQUEST_url_ATTR, and then retrieve the URL in GlobalFilter according to this attribute for use.

Example

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

For example, it is set here to route a new url according to X-New-Url. if the following code is executed, the request /baidu will turn to the request 163

curl -i -H "X-New-Url: http://news.163.com" localhost:10000/baidu

Summary

The function implemented by RequestHeaderToRequestUriGateWayfilter is to read the url of the new route according to the header specified in the configuration file. It is relatively strong and can be used in scenes such as gray scale and production positioning problems.

doc