聊聊spring cloud gateway的PrefixPath及StripPrefix功能

本文主要研究一下spring cloud gateway的PrefixPath及StripPrefix功能html

PrefixPathGatewayFilterFactory

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

public class PrefixPathGatewayFilterFactory extends AbstractGatewayFilterFactory<PrefixPathGatewayFilterFactory.Config> {

    private static final Log log = LogFactory.getLog(PrefixPathGatewayFilterFactory.class);

    public static final String PREFIX_KEY = "prefix";

    public PrefixPathGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PREFIX_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {

            boolean alreadyPrefixed = exchange.getAttributeOrDefault(GATEWAY_ALREADY_PREFIXED_ATTR, false);
            if (alreadyPrefixed) {
                return chain.filter(exchange);
            }
            exchange.getAttributes().put(GATEWAY_ALREADY_PREFIXED_ATTR, true);

            ServerHttpRequest req = exchange.getRequest();
            addOriginalRequestUrl(exchange, req.getURI());
            String newPath = config.prefix + req.getURI().getRawPath();

            ServerHttpRequest request = req.mutate()
                    .path(newPath)
                    .build();

            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());

            if (log.isTraceEnabled()) {
                log.trace("Prefixed URI with: "+config.prefix+" -> "+request.getURI());
            }

            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    public static class Config {
        private String prefix;

        public String getPrefix() {
            return prefix;
        }

        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    }
}
能夠看到這裏使用config的prefix構造newPath,而後構造新的ServerHttpRequest

實例

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://example.org
        filters:
        - PrefixPath=/mypath
好比:請求/hello,最後轉發到目標服務的路徑變爲/mypath/hello

StripPrefixGatewayFilterFactory

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

/**
 * This filter removes the first part of the path, known as the prefix, from the request
 * before sending it downstream
 * @author Ryan Baxter
 */
public class StripPrefixGatewayFilterFactory extends AbstractGatewayFilterFactory<StripPrefixGatewayFilterFactory.Config> {

    public static final String PARTS_KEY = "parts";

    public StripPrefixGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARTS_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) ->  {
            ServerHttpRequest request = exchange.getRequest();
            addOriginalRequestUrl(exchange, request.getURI());
            String path = request.getURI().getRawPath();
            String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(path, "/"))
                    .skip(config.parts).collect(Collectors.joining("/"));
            ServerHttpRequest newRequest = request.mutate()
                    .path(newPath)
                    .build();

            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());

            return chain.filter(exchange.mutate().request(newRequest).build());
        };
    }

    public static class Config {
        private int parts;

        public int getParts() {
            return parts;
        }

        public void setParts(int parts) {
            this.parts = parts;
        }
    }
}
能夠看到這裏的parts指定要去除的前綴的個數,而後使用stream的skip來去除掉相應前綴,而後獲得newPath,構造newRequest

實例

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: http://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2
好比,請求/name/bar/foo,去除掉前面兩個前綴以後,最後轉發到目標服務的路徑爲/foo

小結

PrefixPathGatewayFilterFactory及StripPrefixGatewayFilterFactory是一對針對請求url前綴進行處理的filter工廠,前者添加prefix,後者去除prefix。app

doc

相關文章
相關標籤/搜索