™技术博客

Spring | 2.网关的全局过滤器与局部过滤器

2021年8月15日

全局过滤器GlobalFilter

springcloud版本 2020版本


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
@Component
public class AiopsRequestGlobalFilter implements GlobalFilter, Ordered {

/**
* Process the Web request and (optionally) delegate to the next {@code WebFilter}
* through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 清洗请求头中from 参数
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> httpHeaders.remove(SecurityConstants.FROM)).build();

// 2. 重写StripPrefix
addOriginalRequestUrl(exchange, request.getURI());
String rawPath = request.getURI().getRawPath();
String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")).skip(1L)
.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.mutate().build()).build());
}

@Override
public int getOrder() {
return -1000;
}

}

AbstractGatewayFilterFactory 局部过滤器


  • 内部类写法,是为了指定过滤器的优先级,要优先于全局过滤器
  • 否则容易造成全局过滤器 拦截到指定 局部过滤器的配置内容,从而导致局部过滤器失效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class PreviewGatewayFilter extends AbstractGatewayFilterFactory {

private static final String TOKEN = "token";

@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();

// GET,直接向下执行
if (StrUtil.equalsIgnoreCase(request.getMethodValue(), HttpMethod.GET.name())
|| StrUtil.containsIgnoreCase(request.getURI().getPath(), TOKEN)) {
return chain.filter(exchange);
}

log.warn("演示环境不能操作-> {},{}", request.getMethodValue(), request.getURI().getPath());
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.LOCKED);
return response.setComplete();
};
}

}

扫描二维码,分享此文章