Fork me on GitHub

Spring Cloud Gateway的PrefixPath及StripPrefix功能

目录

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

PrefixPathGatewayFilterFactory

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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

实例

1
2
3
4
5
6
7
8
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.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* 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

实例

1
2
3
4
5
6
7
8
9
10
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。

doc

相关文章