这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战。
上篇文章我们介绍了SpringCloud Gateway Filter的相关概念,并解读了一个全局过滤器——RouteToRequestUrlFilter的filter方法,这篇文章我们来介绍一下两个局部过滤器。
解读SpringCloud Gateway Filter(下)
全局过滤器是实现GlobalFilter, Ordered接口,局部过滤器是实现GatewayFilter, Ordered接口,然后再去实现对应的apply方法。
1、添加前缀的局部过滤器 PrefixPathGatewayFilterFacotry
可以看出来,这是一个局部过滤器的工厂,在工厂内实现了一个局部过滤器。有一个属性 PREFIX_KEY,是指明需要在url上增加的前缀。
接下来看下代码实现。
1 | scss复制代码public GatewayFilter apply(PrefixPathGatewayFilterFactory.Config config) { |
alreadyPrefixed是boolean类型,用来校验一下是否已经添加前缀了,通过exchange.getAttributeOrDefault中的GATEWAY_ALREADY_PREFIXED_ATTR属性来判断,默认值为false。
接下来使用config的Prefix去构造新的路径,新的HttpRequest。先根据exchange.getRequest()获取请求对应的request,然后根据request获取到对应的url,然后在url上去添加一个前缀生成新的path,用这个新的path去构造新的ServerHttpRequest。
举个例子,假如有个简单的静态路由配置如下:
1 | yaml复制代码spring: |
假如现在有个请求/hello,命中了上方的配置,那么这个添加前缀的局部过滤器就会将这个请求变成:http://example/org/mypath/hello。
2、去除前缀的局部过滤器 StripPrefixGatewayFilterFactory
strip是跳过的意思,所以该过滤器是用来去掉前缀的。
1 | scss复制代码public GatewayFilter apply(StripPrefixGatewayFilterFactory.Config config) { |
通过request.getURI().getRawPath()去获取原始的URI,然后根据配置的parts部分去执行.skip(config.parts)去掉前缀。parts是int类型,也就是指定一个数字,去掉几个前缀的部分。
然后将获取到的新path去构造一个新的request再进行转发。
举个例子,假如有个简单的静态路由配置如下:
1 | yaml复制代码spring: |
如果这时候有个请求是/name/bar/foo命中了上方的配置,那么这个请求就会变成/foo,要注意的是,这个stripPrefix=2指的是去掉两个”/xxx”,而不是字符!
SpringCloud Gateway Filter 的执行流程
1、过滤器有优先级之分,Order越大,优先级就越低,越晚被执行。可以通过getOrder方法获取Order。
2、全局过滤器所有的请求都会执行,这是默认的行为,不需要做额外的操作,针对自定义的全局过滤器也是如此。
3、局部过滤器只有配置的请求才会执行,配置在路由配置中,之后文章会介绍如何配置才会使其生效。
自定义局部过滤器的步骤
1、自定义局部过滤器实现GatewayFilter, Ordered 这两个接口中的相应方法。
2、将自定义的局部过滤器加入到过滤器工厂中,并将工厂加入到Spring IOC容器中,工厂继承 AbstractGatewayFilterFactory 抽象类。
3、配置文件中配置过滤器,使其生效。
本文转载自: 掘金