本文主要研究一下spring cloud gateway的PrefixPath及StripPrefix功能html
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
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