千家信息网

spring cloud gateway-过滤器的使用方法

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章主要讲解了"spring cloud gateway-过滤器的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"spring cloud
千家信息网最后更新 2025年12月02日spring cloud gateway-过滤器的使用方法

这篇文章主要讲解了"spring cloud gateway-过滤器的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"spring cloud gateway-过滤器的使用方法"吧!

一、概述

  在Spring-Cloud-Gateway之请求处理流程中最终网关是将请求交给过滤器链表进行处理。

  核心接口:GatewayFilter,GlobalFilter,GatewayFilterChain。

查看整体类图

  

二、网关过滤器作用

  

  当使用微服务构建整个 API 服务时,一般有许多不同的应用在运行,如上图所示的mst-user-servicemst-good-servicemst-order-service,这些服务都需要对客户端的请求的进行 Authentication。最简单粗暴的方法就是像上图一样,为每个微服务应用都实现一套用于校验的过滤器或拦截器。

  通过前置的网关服务来完成这些非业务性质的校验。

  

三、Filter 的生命周期

  Spring Cloud Gateway 的 Filter 的生命周期有两个:"pre" 和 "post"。

  

  "pre"和 "post" 分别会在请求被执行前调用和被执行后调用,和 Zuul Filter 或 Spring Interceptor 中相关生命周期类似,但在形式上有些不一样。

  Zuul 的 Filter 是通过filterType()方法来指定,一个 Filter 只能对应一种类型,要么是 "pre" 要么是"post"。Spring Interceptor 是通过重写HandlerInterceptor中的三个方法来实现的。而 Spring Cloud Gateway 基于 Project Reactor 和 WebFlux,采用响应式编程风格,打开它的 Filter 的接口GatewayFilter你会发现它只有一个方法filter

四、核心接口解读

4.1、GatewayFilterChain--网关过滤链表

/** * 网关过滤链表接口 * 用于过滤器的链式调用 */public interface GatewayFilterChain {    /**     *  链表启动调用入口方法*/    Mono filter(ServerWebExchange exchange);}

默认实现

  /**     * 网关过滤的链表,用于过滤器的链式调用     * 过滤器链表接口的默认实现,     * 包含2个构建函数:     *  1.集合参数构建用于初始化吧构建链表     *  2. index,parent参数用于构建当前执行过滤对应的下次执行的链表      */    private static class DefaultGatewayFilterChain implements GatewayFilterChain {        /**         * 当前过滤执行过滤器在集合中索引         */        private final int index;        /**         * 过滤器集合         */        private final List filters;        public DefaultGatewayFilterChain(List filters) {            this.filters = filters;            this.index = 0;        }        /**         * 构建         * @param parent 上一个执行过滤器对应的FilterChain         * @param index  当前要执行过滤器的索引         */        private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {            this.filters = parent.getFilters();            this.index = index;        }        public List getFilters() {            return filters;        }        /**         * @param exchange the current server exchange         * @return         */        @Override        public Mono filter(ServerWebExchange exchange) {            return Mono.defer(() -> {                if (this.index < filters.size()) {                    //获取当前索引的过滤器                    GatewayFilter filter = filters.get(this.index);                    //构建当前索引的下一个过滤器的FilterChain                    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);                    //调用过滤器的filter方法执行过滤器                    return filter.filter(exchange, chain);                } else {                    //当前索引大于等于过滤集合大小,标识所有链表都已执行完毕,返回空                    return Mono.empty(); // complete                }            });        }    }

过滤器的GatewayFilterChain 执行顺序

  1. 通过GatewayFilter集合构建顶层的GatewayFilterChain

  2. 调用顶层GatewayFilterChain,获取第一个Filter,并创建下一个Filter索引对应的GatewayFilterChain

  3. 调用filter的filter方法执行当前filter,并将下次要执行的filter对应GatewayFilterChain传入。

4.2、GatewayFilter--网关路由过滤器

/** * 网关路由过滤器, * Contract for interception-style, chained processing of Web requests that may * be used to implement cross-cutting, application-agnostic requirements such * as security, timeouts, and others. Specific to a Gateway * */public interface GatewayFilter extends ShortcutConfigurable {    String NAME_KEY = "name";    String VALUE_KEY = "value";    /**     *  过滤器执行方法     * 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} to indicate when request processing is complete     */    Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);}

网关过滤器接口,有且只有一个方法filter,执行当前过滤器,并在此方法中决定过滤器链表是否继续往下执行。

1️⃣、OrderedGatewayFilter--排序

/** * 排序的网关路由过滤器,用于包装真实的网关过滤器,已达到过滤器可排序 */public class OrderedGatewayFilter implements GatewayFilter, Ordered {    //目标过滤器    private final GatewayFilter delegate;    //排序字段    private final int order;    public OrderedGatewayFilter(GatewayFilter delegate, int order) {        this.delegate = delegate;        this.order = order;    }    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        return this.delegate.filter(exchange, chain);    }}

OrderedGatewayFilter实现类主要目的是为了将目标过滤器包装成可排序的对象类型。是目标过滤器的包装类

2️⃣、GatewayFilterAdapter

  /**     * 全局过滤器的包装类,将全局路由包装成统一的网关过滤器     */    private static class GatewayFilterAdapter implements GatewayFilter {        /**         * 全局过滤器         */        private final GlobalFilter delegate;        public GatewayFilterAdapter(GlobalFilter delegate) {            this.delegate = delegate;        }        @Override        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {            return this.delegate.filter(exchange, chain);        }    }

GatewayFilterAdapter实现类主要目的是为了将GlobalFilter过滤器包装成GatewayFilter类型的对应。是GlobalFilter过滤器的包装类

4.3、GlobalFilter

  

  GlobalFilter 为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,模式系统初始化时加载,并作用在每个路由上

1️⃣、初始化加载,通过GatewayAutoConfiguration自动创建

//GatewayAutoConfiguration 类        /**         * 全局过滤器,用户通过HttpClient转发请求         */        @Bean        public NettyRoutingFilter routingFilter(HttpClient httpClient,                                                ObjectProvider> headersFilters) {            return new NettyRoutingFilter(httpClient, headersFilters);        }        /**         * 全局的过滤器,用户将HttpClient客户端转发请求的响应写入到原始的请求响应中         */        @Bean        public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {            return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());        }        //GatewayLoadBalancerClientAutoConfiguration 类    /**     * 全局过滤器,用于在通过负载均衡客户端选择服务实例信息     */    @Bean    @ConditionalOnBean(LoadBalancerClient.class)    public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {        return new LoadBalancerClientFilter(client);    }

2️⃣、GlobalFilter转换成GatewayFilter,并作用于每个路由上,在FilteringWebHandler实现

//FilteringWebHandler类    /**     * 包装加载全局的过滤器,将全局过滤器包装成GatewayFilter     */    private static List loadFilters(List filters) {        return filters.stream()                .map(filter -> {                    //将所有的全局过滤器包装成网关过滤器                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);                    //判断全局过滤器是否实现了可排序接口                    if (filter instanceof Ordered) {                        int order = ((Ordered) filter).getOrder();                        //包装成可排序的网关过滤器                        return new OrderedGatewayFilter(gatewayFilter, order);                    }                    return gatewayFilter;                }).collect(Collectors.toList());    }    @Override    public Mono handle(ServerWebExchange exchange) {        //获取请求上下文设置的路由实例        Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);        //获取路由定义下的网关过滤器集合        List gatewayFilters = route.getFilters();        //组合全局的过滤器与路由配置的过滤器        List combined = new ArrayList<>(this.globalFilters);        //添加路由配置过滤器到集合尾部        combined.addAll(gatewayFilters);        //对过滤器进行排序        //TODO: needed or cached?        AnnotationAwareOrderComparator.sort(combined);        logger.debug("Sorted gatewayFilterFactories: "+ combined);        //创建过滤器链表对其进行链式调用        return new DefaultGatewayFilterChain(combined).filter(exchange);    }
  • loadFilters方法是将全局路由使用GatewayFilterAdapter包装成GatewayFilter

  • handle方法

    • 获取当前请求使用的路由Route

    • 获取路由配置的过滤器集合route.getFilters()

    • 合并全过滤器与路由配置过滤器combined

    • 对过滤器排序AnnotationAwareOrderComparator.sort

    • 通过过滤器集合构建顶级链表DefaultGatewayFilterChain,并对其当前请求调用链表的filter方法。

小结

Spring-Cloud-Gateway的过滤器接口分为两种:

  1. GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器

  2. GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上

五、GatewayFilterFactory 配置路由过滤器

  路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路径过滤器的范围限定为特定路径。

1️⃣、加载GatewayFilter

  在路由定位器中以及看到了通过路由定义转换路由方法,其中包含了通过过滤器定义(FilterDefinition)转换过滤器(GatewayFilter)的部分,在RouteDefinitionRouteLocator类中源码如下:

/**     * 加载过滤器,根据过滤器的定义加载     */    @SuppressWarnings("unchecked")    private List loadGatewayFilters(String id, List filterDefinitions) {        //遍历过滤器定义,将过滤器定义转换成对应的过滤器        List filters = filterDefinitions.stream()                .map(definition -> {                    //通过过滤器定义名称获取过滤器创建工厂                    GatewayFilterFactory factory = this.gatewayFilterFactories.get(definition.getName());                    if (factory == null) {                        throw new IllegalArgumentException("Unable to find GatewayFilterFactory with name ">getFilters方法 合并配置中的全局过滤器与路由自身配置的过滤器,并对其排序(全局配置过滤器信息通过gatewayProperties.getDefaultFilters()获取)loadGatewayFilters 依次遍历路由定义下的FilterDefinition并将其通过对应的GatewayFilterFactory转换为GatewayFilter对象。2️⃣、GatewayFilterFactory配置过滤器创建工厂创建GatewayFilter对象  默认内置很多GatewayFilterFactory实现类,用于创建作用不同的网关过滤器。类图  子类及其划分3️⃣、AddResponseHeaderGatewayFilterFactory 创建解析/** * * 响应header添加数据过滤器 * 用户在response header中添加配置数据 */public class AddResponseHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {    @Override    public GatewayFilter apply(NameValueConfig config) {        return (exchange, chain) -> {            //获取Response并将配置的数据添加到header中            exchange.getResponse().getHeaders().add(config.getName(), config.getValue());            return chain.filter(exchange);        };    }}。 配置示例:spring:  cloud:    gateway:      default-filters:      - AddResponseHeader=X-Response-Default-Foo, Default-Bar AddResponseHeader=X-Response-Default-Foo, Default-Bar 会被解析成FilterDefinition对象 (name =AddResponseHeader ,args= [X-Response-Default-Foo,Default-Bar])通FilterDefinition的Name找到AddResponseHeaderGatewayFilterFactory工厂通过FilterDefinition 的args 创建Config对象(name=X-Response-Default-Foo,value=Default-Bar)通过 AddResponseHeaderGatewayFilterFactory工厂的apply方法传入config创建GatewayFilter对象。4️⃣、全部配置5.1、请求头spring:  cloud:    gateway:      routes:      - id: add_request_header_route        uri: http://example.org        filters:        - AddRequestHeader=X-Request-Foo, Bar 名称和值,这将为所有匹配请求的下游请求标头添加X-Request-Foo:Bar标头。移除请求头filters:        - RemoveRequestHeader=X-Request-Foo 5.2、请求参数filters:        - AddRequestParameter=foo, bar 这会将foo = bar添加到下游请求的所有匹配请求的查询字符串中。5.3、添加响应头filters:        - AddResponseHeader=X-Response-Foo, Bar 这会将X-Response-Foo:Bar标头添加到所有匹配请求的下游响应标头中。移除响应头filters:        - RemoveResponseHeader=X-Response-Foo 设置响应头filters:        - SetResponseHeader=X-Response-Foo, Bar 此GatewayFilter将替换具有给定名称的所有标头,而不是添加。5.4、路径前缀filters:        - PrefixPath=/mypath 这将使/ mypath前缀为所有匹配请求的路径。所以对/ hello的请求会被发送到/ mypath / hello。5.5、原始主机头没有参数,此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始主机头,而不是http客户端确定的主机头。filters:        - PreserveHostHeader 5.6、重定向filters:        - RedirectTo=302, http://acme.org 这将发送带有Location:http://acme.org标头的状态302以执行重定向。5.7、重写路径predicates:        - Path=/foo/**        filters:        - RewritePath=/foo/(?.*), /$\{segment} 对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。注意由于YAML规范,$ \替换为$。5.8、保存Sessionpredicates:        - Path=/foo/**        filters:        - SaveSession 5.9、路径模板SetPath GatewayFilter Factory采用路径模板参数。它提供了一种通过允许模板化路径段来操作请求路径的简单方法。predicates:        - Path=/foo/{segment}        filters:        - SetPath=/{segment} 对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。5.10、设置响应状态spring:  cloud:    gateway:      routes:      - id: setstatusstring_route        uri: http://example.org        filters:        - SetStatus=BAD_REQUEST      - id: setstatusint_route        uri: http://example.org        filters:        - SetStatus=401 5.11、请求参数剥离parts参数指示在将请求发送到下游之前从请求中剥离的路径中的部分数。predicates:        - Path=/name/**        filters:        - StripPrefix=2 当通过网关向/ name / bar / foo发出请求时,对nameservice的请求将类似于http:// nameservice / foo。5.12、重试retries:重试:应该尝试的重试次数statuses:状态:应该重试的HTTP状态代码,使用org.springframework.http.HttpStatus表示methods:方法:应该重试的HTTP方法,使用org.springframework.http.HttpMethod表示series:系列:要重试的状态代码系列,使用org.springframework.http.HttpStatus.Series表示routes:      - id: retry_test        uri: http://localhost:8080/flakey        predicates:        - Host=*.retry.com        filters:        - name: Retry          args:            retries: 3            statuses: BAD_GATEWAY 5.13、Hystrix GatewayFilter Factoryhttps://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_hystrix_gatewayfilter_factory5.14、请求限速   RequestRateLimiter GatewayFilter Factory5.15、安全头  SecureHeaders GatewayFilter Factory

感谢各位的阅读,以上就是"spring cloud gateway-过滤器的使用方法"的内容了,经过本文的学习后,相信大家对spring cloud gateway-过滤器的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0