从专栏的第二十四篇博客可以知道,请求被路由到微服务之前以及微服务响应请求回网关之前,都会经过一连串的过滤器。

过滤器的主要作用就是在请求的传递过程中,对请求和响应做一些手脚。
在Gateway中, Filter的生命周期只有两个,PRE 和 POST,PRE这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。 POST这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

过滤器分为局部过滤器(GatewayFilter) 和全局过滤器(GlobalFilter) ,GatewayFilter主要是应用到单个路由或者一个分组的路由上,而GlobalFilter则是应用到所有的路由上 。

在SpringCloud Gateway中也内置了很多不同类型的网关路由过滤器,一般情况下,内置的网关路由过滤器基本能够满足开发需求,不过如果想要自定义网关路由过滤器,也是可以的。和上篇博客思路一样,找到一个内置的网关路由过滤器,如RewritePathGatewayFilterFactory,查看它的源码,然后可以得出自定义网关路由过滤器,需要满足的2个前提条件,一是自定义网关路由过滤器的名字必须是配置+GatewayFilterFactory,二是自定义网关路由过滤器类必须继承AbstractGatewayFilterFactory<配置类>。接下来要实现一个能够根据配置,来选择开启缓存日志或者是控制台日志的过滤器。

新建一个过滤器类LogGatewayFilterFactory,信息如下:

package com.example.apigateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

//自定义局部过滤器
@Component
public class LogGatewayFilterFactory
        extends AbstractGatewayFilterFactory<LogGatewayFilterFactory.Config> {

    //构造函数
    public LogGatewayFilterFactory() {
        super(Config.class);
    }

    /**
     * 读取配置文件中的参数,赋值到配置类中
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("consoleLog", "cacheLog");
    }

    /**
     * 过滤器逻辑
     * @param config
     * @return
     */
    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                if (config.isConsoleLog()) {
                    System.out.println("consoleLog已经开启了....");
                }
                if (config.isCacheLog()) {
                    System.out.println("cacheLog已经开启了....");
                }


                return chain.filter(exchange);
            }
        };
    }

    /**
     * 配置类,接收配置参数
     */
    public static class Config {
        private boolean consoleLog;
        private boolean cacheLog;

        public boolean isConsoleLog() {
            return consoleLog;
        }

        public void setConsoleLog(boolean consoleLog) {
            this.consoleLog = consoleLog;
        }

        public boolean isCacheLog() {
            return cacheLog;
        }

        public void setCacheLog(boolean cacheLog) {
            this.cacheLog = cacheLog;
        }
    }
}

在order_route路由加上log的网关过滤器配置,如下:

spring gateway 服务转发_spring gateway 服务转发


表示开启consoleLog,不开启cacheLog。浏览器访问http://localhost:8888/api/order/message1,结果如下:

spring gateway 服务转发_spring_02

说明局部过滤器定义成功,接下里就是尝试定义全局过滤器了。