快捷搜索: 王者荣耀 脱发

Spring Cloud 网关路由—Spring Cloud Gateway 自定义过滤器

在一篇我们详细介绍了Spring Cloud Gateway路由的配置与使用,并且介绍了部分过滤器的配置,不过我们配置的都是Spring Cloud Gateway内部定义的过滤器和断言,本篇博客讲解如何创建自定义断言与过滤器的使用。

自定义断言工厂需要实现RoutePredicateFactory,不过Spring Cloud Gateway为我们提供了一个抽象类,我们只需要继承该抽象类AbstractRoutePredicateFactory 即可。如下为自定义断言工厂的一个示例。

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
    public MyRoutePredicateFactory() {
        super(Config.class);
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //获取请求
            ServerHttpRequest request = exchange.getRequest();
            //判断请求是否与配置匹配
            return matches(config, request);
        };
    }
    public static class Config {
      //为断言配置属性
    }
}

与断言工厂类似,GatewayFilter的自定义需要实现GatewayFilterFactory接口,它也给我们提供了一个抽象类,我们只需继承该类AbstractGatewayFilterFactory即可,如下为自定义GatewayFilter的一个示例。

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
    public PreGatewayFilterFactory() {
	super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
	return (exchange, chain) -> {
	    //If you want to build a "pre" filter you need to manipulate the
	    //request before calling chain.filter
	    ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
	    //use builder to manipulate the request
	    return chain.filter(exchange.mutate().request(request).build());
	};
    }

    public static class Config {
	//Put the configuration properties for your filter here
    }
}

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
    public PostGatewayFilterFactory() {
	super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
	// grab configuration from Config object
	return (exchange, chain) -> {
	    return chain.filter(exchange).then(Mono.fromRunnable(() -> {
		ServerHttpResponse response = exchange.getResponse();
				//Manipulate the response in some way
	    }));
	};
    }

    public static class Config {
	//Put the configuration properties for your filter here
    }

}

上面的两个示例为官方文档提供的两个示例,其中第一个为更改request请求的内容,第二个示例为更改response响应的内容,我们在编写自定义过滤器之前,最好可以先阅读源码中的一些过滤器作为示范。自定义GlobalFilter全局过滤器时需要实现GlobalFilter接口,如下示例为官方文档提供的两种自定义GlobalFilter示例:

@Bean
public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //添加请求头
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds 响应头
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}

Spring Cloud Gateway的使用就介绍三篇,其源码这里不再讲解,有兴趣的可以自行阅读Spring Cloud Gateway源码,后续有时间也会更新一些源码的内容,下面的部分将介绍分布式消息Spring Cloud Stream的使用。

经验分享 程序员 微信小程序 职场和发展