gateway中的局部过滤器_010-spring cloud gateway-过滤器-自定义局部、全局过滤器、区别...

本文介绍了如何在Spring Cloud Gateway中自定义局部过滤器和全局过滤器。局部过滤器(GatewayFilter)用于单个或一组路由,例如统计响应时间,配置时与RouteLocator结合使用。全局过滤器(GlobalFilter)应用于所有路由,如令牌校验,可以通过注册Bean的方式实现。文中还探讨了两者的主要区别和应用场景。
摘要由CSDN通过智能技术生成

一、自定义局部过滤器

自定义过滤器需要实现GatewayFilter和Ordered。其中GatewayFilter中的这个方法就是用来实现你的自定义的逻辑的

Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);

示例:统计某个服务的响应时间

1.1、创建Filer

public class ElapsedFilter implementsGatewayFilter, Ordered {private static final Log log = LogFactory.getLog(GatewayFilter.class);private static final String ELAPSED_TIME_BEGIN = "elapsedTimeBegin";

@Overridepublic Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {

exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis());returnchain.filter(exchange).then(

Mono.fromRunnable(()->{

Long startTime=exchange.getAttribute(ELAPSED_TIME_BEGIN);if (startTime != null) {

log.info(exchange.getRequest().getURI().getRawPath()+ ": " + (System.currentTimeMillis() - startTime) + "ms");

}

})

);

}

@Overridepublic intgetOrder() {returnOrdered.LOWEST_PRECEDENCE;

}

}

在请求刚刚到达时,往ServerWebExchange中放入了一个属性elapsedTimeBegin,属性值为当时的毫秒级时间戳。然后在请求执行结束后,又从中取出我们之前放进去的那个时间戳,与当前时间的差值即为该请求的耗时。因为这是与业务无关的日志所以将Ordered设为Integer.MAX_VALUE以降低优先级。

chain.filter(exchange)之前的就是 “pre” 部分,之后的也就是then里边的是 “post” 部分。

1.2、配置

创建好 Filter 之后我们将它添加到我们的 Filter Chain 里边

@BeanpublicRouteLocator customerRouteLocator(RouteLocatorBuilder builder) {//@formatter:off

returnbuilder.routes()

.route(r-> r.path("/fluent/customer/**")

.filters(f-> f.stripPrefix(2)

.filter(newElapsedFilter())

.addResponseHeader("X-Response-Default-Foo", "Default-Bar"))

.uri("lb://CONSUMER")

.order(0)

.id("fluent_customer_service")

)

.build();//@formatter:on

}

注意:实际在使用 Spring Cloud 的过程中,需要使用 Sleuth+Zipkin 来进行耗时分析。

二、全局过滤器

有多个路由就需要一个一个来配置,并不能通过像下面这样来实现全局有效(也未在 Fluent Java API 中找到能设置 defaultFilters 的方法)

@BeanpublicElapsedFilter elapsedFilter(){return newElapsedFilter();

}

自定义过滤器需要实现GlobalFilter和Ordered。

示例:校验token

2.1、创建Filter

public class TokenFilter implementsGlobalFilter, Ordered {

@Overridepublic Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {

String token= exchange.getRequest().getQueryParams().getFirst("token");if (token == null ||token.isEmpty()) {

exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);returnexchange.getResponse().setComplete();

}returnchain.filter(exchange);

}

@Overridepublic intgetOrder() {return -100;

}

}

2.2、在 Spring Config 中配置这个 Bean

@BeanpublicTokenFilter tokenFilter(){return newTokenFilter();

}

三、GatewayFilter与GlobalFilter的区别

3.1、GatewayFilter

在一个高的角度来看,Global filters会被应用到所有的路由上,而Gateway filter将应用到单个路由上或者一个分组的路由上。

GatewayFilter是从WebFilter中Copy过来的,相当于一个Filter过滤器,可以对访问的URL过滤横切处理,应用场景比如超时,安全等。

GatewayFilter和GlobalFilter两个接口中定义的方法一样都是Mono filter(ServerWebExchange exchange, GatewayFilterChain chain),唯一的区别就是GatewayFilter继承了ShortcutConfigurable,GlobalFilter没有任何继承。

参看示例一:Gateway Filter与RouteLocator绑定使用

3.2、GlobalFilter

Spring Cloud gateway定义了GlobalFilter的接口让我们去自定义实现自己的的GlobalFilter。GlobalFilter是一个全局的Filter,作用于所有的路由。

让其在Gateway中运行生效,有两种方式一种直接加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
除了全局过滤器之外,Spring Cloud Gateway还提供了局部过滤器的功能,可以对某个路由进行特定的处理。 使用局部过滤器,需要在路由配置添加一个filters属性,并且在该属性指定过滤器的名称或者类名。例如: ```yaml spring: cloud: gateway: routes: - id: myRoute uri: http://localhost:8080 predicates: - Path=/myPath/** # 添加一个局部过滤器 filters: - MyLocalFilter ``` 上面的配置,我们为名为myRoute的路由添加了一个局部过滤器MyLocalFilter,该过滤器可以是一个Bean的名称或者一个类的全限定名。如果是一个类的全限定名,则需要通过@Component或者@Bean注解将该类加入到Spring容器。 在局部过滤器,同样需要实现GatewayFilter接口,并且实现filter方法。在该方法,可以对请求进行特定的处理,例如添加请求头、修改请求体等。 下面是一个示例代码: ```java @Component public class MyLocalFilter implements GatewayFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 在请求头添加一个自定义的token exchange.getRequest().mutate().header("token", "myToken").build(); // 继续执行过滤器链 return chain.filter(exchange); } } ``` 在上面的代码,我们实现了一个局部过滤器,将一个自定义的token添加到请求头,并且继续执行过滤器链。在这个过程,可以通过exchange对象获取到请求、响应等信息。 需要注意的是,局部过滤器只对指定的路由进行处理,如果需要对多个路由进行相同的处理,可以将该过滤器添加到多个路由的filters属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值