Gateway全局过滤器
Spring Cloud Gateway 是一个强大的 API 网关,用于管理和路由微服务架构中的请求。全局过滤器(Global Filters)是 Gateway 中的一个核心概念,它允许你在所有路由请求上应用统一的逻辑。本文将详细介绍全局过滤器的概念、实现方式以及实际应用场景。
什么是全局过滤器?
全局过滤器是 Spring Cloud Gateway 中的一种过滤器类型,它会在所有路由请求上执行。与特定路由的过滤器不同,全局过滤器不需要显式配置在某个路由上,而是自动应用于所有请求。这使得全局过滤器非常适合实现跨路由的通用逻辑,例如身份验证、日志记录、请求修改等。
全局过滤器的工作原理
全局过滤器通过实现 GlobalFilter
接口来定义。Spring Cloud Gateway 会在请求进入网关时,依次调用所有注册的全局过滤器。每个过滤器可以对请求进行修改、记录或拦截,然后将请求传递给下一个过滤器或路由。
全局过滤器的生命周期
- Pre-filtering:在请求被路由之前执行,通常用于修改请求头、记录日志或进行身份验证。
- Routing:请求被路由到目标服务。
- Post-filtering:在响应返回客户端之前执行,通常用于修改响应头或记录响应日志。
实现一个全局过滤器
下面是一个简单的全局过滤器示例,它会在所有请求中添加一个自定义的请求头。
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 添加自定义请求头
exchange.getRequest().mutate().header("X-Custom-Header", "GlobalFilter").build();
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // 设置过滤器的执行顺序
}
}
在这个示例中,CustomGlobalFilter
实现了 GlobalFilter
接口,并在 filter
方法中添加了一个自定义请求头 X-Custom-Header
。getOrder
方法用于指定过滤器的执行顺序,数值越小,优先级越高。
实际应用场景
1. 身份验证
全局过滤器可以用于实现统一的身份验证逻辑。例如,你可以在全局过滤器中检查请求头中的 Authorization
字段,验证用户的身份,并在验证失败时返回 401 状态码。
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
2. 请求日志记录
全局过滤器还可以用于记录所有进入网关的请求日志,便于后续的监控和分析。
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Request received: {} {}", exchange.getRequest().getMethod(), exchange.getRequest().getURI());
return chain.filter(exchange);
}
3. 请求修改
在某些情况下,你可能需要修改请求的内容或头信息。例如,你可以在全局过滤器中为所有请求添加一个 X-Forwarded-For
头,记录客户端的原始 IP 地址。
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
exchange.getRequest().mutate().header("X-Forwarded-For", clientIp).build();
return chain.filter(exchange);
}
总结
全局过滤器是 Spring Cloud Gateway 中一个非常强大的功能,它允许你在所有路由请求上应用统一的逻辑。通过实现 GlobalFilter
接口,你可以轻松地实现身份验证、日志记录、请求修改等功能。全局过滤器的执行顺序可以通过 getOrder
方法来控制,确保过滤器按照预期的顺序执行。
附加资源
练习
- 实现一个全局过滤器,记录所有请求的响应时间。
- 修改上面的身份验证示例,使其支持 JWT 令牌验证。
- 尝试在全局过滤器中实现请求限流功能。
在实现全局过滤器时,务必考虑过滤器的执行顺序,以确保逻辑的正确性。