本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Spring Cloud Gateway-自定义断言及过滤器
在使用Spring Cloud Gateway的过程中,除了使用其内置的断言和过滤器外,有时候可能还需要实现一些特定的业务,这种情况下我们需要自定义实现断言及过滤器,这篇将为同学们介绍一下怎么在Spring Cloud Gateway中实现自定义断言及过滤器。
自定义断言
实现自定义断言,需要实现RoutePredicateFactory 接口并实例化为Spring Bean,也可以通过继承AbstractRoutePredicateFactory 来实现自定义断言,示例如下:
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
// 获取request
ServerHttpRequest request = exchange.getRequest();
// 判断是否满足自定义需求
return matches(config, request);
};
}
public static class Config {
// 指定自定义断言的参数
}
}
自定义过滤器
实现自定义的过滤器则需要实现GatewayFilterFactory 接口,或者直接继承AbstractGatewayFilterFactory ,示例如下:
// 定义请求过滤器
@Component
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
public PreGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
// 对网关请求数据进行操作
return chain.filter(exchange.mutate().request(builder.build()).build());
};
}
public static class Config {
// 自定义过滤器的参数
}
}
// 定义响应过滤器
@Component
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
// 对网关响应报文进行操作
}));
};
}
public static class Config {
// 自定义过滤器的参数
}
}
当自定义filter的类名以GatewayFilterFactory结尾时,可以用前缀直接在application.yml中配置,与内置过滤器使用方式相同。
自定义全局过滤器
通过实现GlobalFilter 接口,可以自定义全局过滤器。
// 定义请求过滤器
@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal()
.map(Principal::getName)
.defaultIfEmpty("Default User")
.map(userName -> {
exchange.getRequest().mutate().header("TEST-HEADER", userName).build();
return exchange;
})
.flatMap(chain::filter);
}
// 定义响应过滤器
@Bean
public GlobalFilter customGlobalPostFilter() {
return (exchange, chain) -> chain.filter(exchange)
.then(Mono.just(exchange))
.map(serverWebExchange -> {
serverWebExchange.getResponse().getHeaders().set("TEST-HEADER",
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
return serverWebExchange;
})
.then();
}