1.6.2.6 Gateway 高级特性之 Filter 过滤
过滤器 Filter 是用于功能增强的,用于在请求之前(pre)或之后(Post)修改请求和响应信息。具体信息请参考官方网址https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-webflux/gatewayfilter-factories.html。还可以类比 SpringMvc 的拦截器 Interceptor 和 Servlet 的过滤器进行学习。

网关 Gateway 的过滤器 Filter主要又如下作用,即进行哪些功能增强。
- 请求鉴权
- 异常处理
- 统计接口调用时长,重点是大厂面试题。
过滤器 Filter 的类型主要分为3类,如下所示。
- 
全局过滤器 Global Filters 出厂默认的,直接使用即可。作用于所有的路由,不需要在配置文件中配置,实现 GlobalFilter 接口即可。 
- 
单一内置过滤器 GatewayFilter 又称为网关过滤器,主要作用于单一过滤器或某个路由分组。 
- 
自定义过滤器 
1.6.2.6.1 单一内置过滤器
上面我们已经简单的介绍了单一内置过滤器 GatewayFilter,若想了解更多的信息,可参考官方网址https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-webflux/gatewayfilter-factories.html。Spring Cloud Gateway 提供了很多的单一内置过滤器,下面将讲解一些常用的单一内置过滤器。

下面将从5个方面讲解单一内置过滤器,第一组是请求头(RequestHeader)相关组;第二组是请求参数(RequestParameter)相关组;第三组是响应头(ResponseHeader)相关组;第四章是前缀和路径相关组;最后一组是其他组。
1.第一组之 AddRequestHeader GatewayFilter Factory
该网关过滤器工厂用于指定请求头内容 ByName,主要功能是添加请求头参数,AddRequestHeader 拥有两个参数,一个是 name ,另一个是 value,配置在服务网关的 application.yml 文件中,具体的信息可以参考下图所示的信息。

具体的操作步骤如下所示。
- 
在支付微服务 8001 的 PayGatewayController 业务类中添加如下业务方法。 java@GetMapping(value = "/pay/gateway/filter") public ResultData<String> getGatewayFilter(HttpServletRequest request) { String result = ""; Enumeration<String> headers = request.getHeaderNames(); while(headers.hasMoreElements()) { String headName = headers.nextElement(); String headValue = request.getHeader(headName); System.out.println("请求头名: " + headName +"\t\t\t"+"请求头值: " + headValue); if(headName.equalsIgnoreCase("X-Request-atguigu1") || headName.equalsIgnoreCase("X-Request-atguigu2")) { result = result+headName + "\t " + headValue +" "; } } return ResultData.success("getGatewayFilter 过滤器 test: "+result+" \t "+ DateUtil.now()); }
- 
然后在服务网关微服务 9527 的 application.yml 文件中添加如下配置信息,用于服务网关过滤器的功能增强。 yml- id: pay_routh3 #pay_routh3 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/pay/gateway/filter/** # 断言,路径相匹配的进行路由 filters: - AddRequestHeader=X-Request-atguigu1,atguiguValue1 # 请求头kv,若一头含有多参则重写一行设置 - AddRequestHeader=X-Request-atguigu2,atguiguValue2
- 
测试,重新启动支付微服务 8001、负载均衡80、服务网关 9527 和服务链路追踪 Zipkin。然后在浏览器中测试网址http://localhost:9527/pay/gateway/filter。经过对上述网址的测试弹出如下图所示的信息。注意,先启动服务链路追踪 Zipkin。  控制台输入下图所示的信息。  
2.第一组之 RemoveRequestHeader GatewayFilter Factory
该服务网关过滤器工厂用于删除内容 ByName。RemoveRequestHeader 主要用一个参数 name,它是请求头参数的 name,用于删除请求头列表中的对应 name 的请求参数。具体的信息如下图所示。

具体操作如下所示。
- 
配置服务网关 9527 的 application.yml 配置文件,在 filters 中添加 RemoveRequestHeader 过滤工厂。配置文件的具体信息如下所示。 yml- id: pay_routh3 #pay_routh3 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/pay/gateway/filter/** # 断言,路径相匹配的进行路由 filters: - AddRequestHeader=X-Request-atguigu1,atguiguValue1 # 请求头kv,若一头含有多参则重写一行设置 - AddRequestHeader=X-Request-atguigu2,atguiguValue2 - RemoveRequestHeader=sec-fetch-site # 删除请求头sec-fetch-site
- 
测试,启动支付微服务 8001、负载均衡80、服务网关 9527 和服务链路追踪 Zipkin,若未关闭之前的服务,可以只重启服务网关 9527即可。然后在浏览器中测试网址http://localhost:9527/pay/gateway/filter。注意,先启动服务链路追踪 Zipkin。 添加过滤工厂 RemoveRequestHeader 之前,后台输出的请求参数如下图所示。  添加过滤工厂 RemoveRequestHeader 之后,后台输出的请求参数如下图所示。  
3.第一组之 SetRequestHeader GatewayFilter Factory
该服务网关过滤工厂用于修改 ByName。SetRequestHeader 主要有两个参数,分别是 name 和 value参数,name 用于指定请求头的参数 name,value 用于设置新的值,最后达成修改请求头参数的功能,具体的信息如下所示。

具体操作如下所示。
- 
配置服务网关 9527 的 application.yml 配置文件,在 filters 中添加 SetRequestHeader 过滤工厂。配置文件的具体信息如下所示。 yml- id: pay_routh3 #pay_routh3 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/pay/gateway/filter/** # 断言,路径相匹配的进行路由 filters: - AddRequestHeader=X-Request-atguigu1,atguiguValue1 # 请求头kv,若一头含有多参则重写一行设置 - AddRequestHeader=X-Request-atguigu2,atguiguValue2 - RemoveRequestHeader=sec-fetch-site # 删除请求头sec-fetch-site - SetRequestHeader=sec-fetch-mode, Bulue-updatebyleolei # 将请求头sec-fetch-mode对应的值修改为Bulue-updatebyleolei
- 
测试,启动支付微服务 8001、负载均衡80、服务网关 9527 和服务链路追踪 Zipkin,若未关闭之前的服务,可以只重启服务网关 9527即可。然后在浏览器中测试网址http://localhost:9527/pay/gateway/filter。注意,先启动服务链路追踪 Zipkin。 添加过滤工厂 SetRequestHeader 之前,后台输出的请求参数如下图所示。  添加过滤工厂 SetRequestHeader 之前,后台输出的请求参数如下图所示。  如上两图所示,请求头参数 sec-fetch-mode 的值已经成功通过过滤工厂 SetRequestHeader 修改。 
4.第二组之 AddRequestParameter GatewayFilter Factory
该服务网关过滤工厂用于新增请求参数。AddRequestParameter 主要有两个参数,分别是 name 和 value。当服务网关的配置文件中配置号信息后且没有在 url 中携带该参数及其值,后台打印配置文件 application.yml 的值;若在 url 中携带了参数及其值,则后台打印 url 中的新值。具体信息如下所示。

具体操作如下所示。
- 
在支付微服务 8001 的 PayGatewayController 中修改如下所示的业务代码。 java@GetMapping(value = "/pay/gateway/filter") public ResultData<String> getGatewayFilter(HttpServletRequest request) { String result = ""; Enumeration<String> headers = request.getHeaderNames(); while(headers.hasMoreElements()) { String headName = headers.nextElement(); String headValue = request.getHeader(headName); System.out.println("request headName:" + headName +"---"+"request headValue:" + headValue); if(headName.equalsIgnoreCase("X-Request-atguigu1") || headName.equalsIgnoreCase("X-Request-atguigu2")) { result = result+headName + "\t " + headValue +" "; } } System.out.println("============================================="); String customerId = request.getParameter("customerId"); System.out.println("request Parameter customerId: "+customerId); String customerName = request.getParameter("customerName"); System.out.println("request Parameter customerName: "+customerName); System.out.println("============================================="); return ResultData.success("getGatewayFilter 过滤器 test: "+result+" \t "+ DateUtil.now()); }
- 
修改服务网关 9527 的 application.yml 配置文件,在 filters 的过滤器下添加 AddRequestParameter 过滤工厂,主要用于新增请求参数。具体的的配置文件信息如下所示。 java- id: pay_routh3 #pay_routh3 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/pay/gateway/filter/** # 断言,路径相匹配的进行路由 filters: - AddRequestHeader=X-Request-atguigu1,atguiguValue1 # 请求头kv,若一头含有多参则重写一行设置 - AddRequestHeader=X-Request-atguigu2,atguiguValue2 - RemoveRequestHeader=sec-fetch-site # 删除请求头sec-fetch-site - SetRequestHeader=sec-fetch-mode, Blue-updatebyzzyy # 将请求头sec-fetch-mode对应的值修改为Blue-updatebyzzyy - AddRequestParameter=customerId,6666 # 新增请求参数Parameter:k ,v
- 
测试,本下届暂时不测试,用于与 RemoveRequestParameter GatewayFilter Factory 一起测试。 
5.第二组之 RemoveRequestParameter GatewayFilter Factory
改服务网关过滤工厂用于删除请求参数。RemoveRequestParameter 携带了 1 个参数 name,主要用于删除指定 name 的 value,即使 url 中给该参数赋值,请求参数也会被删除。具体的信息如下所示。

具体的操作如下所示。
- 
修改服务网关 9527 的 application.yml 配置文件,在 filters 的过滤器下添加 RemoveRequestParameter 过滤工厂,主要用于删除请求参数。具体的的配置文件信息如下所示。 yml- id: pay_routh3 #pay_routh3 uri: lb://cloud-payment-service #匹配后提供服务的路由地址 predicates: - Path=/pay/gateway/filter/** # 断言,路径相匹配的进行路由 filters: - AddRequestHeader=X-Request-atguigu1,atguiguValue1 # 请求头kv,若一头含有多参则重写一行设置 - AddRequestHeader=X-Request-atguigu2,atguiguValue2 - RemoveRequestHeader=sec-fetch-site # 删除请求头sec-fetch-site - SetRequestHeader=sec-fetch-mode, Blue-updatebyzzyy # 将请求头sec-fetch-mode对应的值修改为Blue-updatebyzzyy - AddRequestParameter=customerId,6666 # 新增请求参数Parameter:k ,v - RemoveRequestParameter=customerName # 删除url请求参数customerName,你传递过来也是null
- 
测试,启动支付微服务 8001、负载均衡80、服务网关 9527 和服务链路追踪 Zipkin,若未关闭之前的服务,可以只重启服务网关 9527即可。然后在浏览器中测试网址http://localhost:9527/pay/gateway/filter和http://localhost:9527/pay/gateway/filter?customerId=9999&customerName=leolei。注意,先启动服务链路追踪 Zipkin。 添加过滤工厂 AddRequestParameter 和 RemoveRequestParameter 后访问网址http://localhost:9527/pay/gateway/filter,后台输出的请求参数如下图所示。  添加过滤工厂 AddRequestParameter 和 RemoveRequestParameter 后访问网址http://localhost:9527/pay/gateway/filter?customerId=9999&customerName=leolei,后台输出的请求参数如下图所示。 
