过滤器
基本使用
以重写过滤器为例
spring:
cloud:
gateway:
routes:
- id: order-route
uri: lb://service-order
predicates:
- name: Path
args:
patterns: /api/order/**
order: 1
filters:
- RewritePath=/api/order?(?<segment>.*), /$\{segment}
例如/api/order/readDb则会被重写为/readDb并转发给service-order服务 其他过滤器用法也基本一致,可以查阅官网 https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories.html
默认过滤器
若想让过滤作用在每一个路由上,则需要使用默认过滤器 例如,向响应头添加自定义标头过滤器
default-filters:
- AddResponseHeader=X-Response-Abc, 123
default-filters要与routes同级
全局过滤器
全局过滤器和默认过滤器都可以对所有的路由生效,但全局过滤器优先级更高 自定义全局过滤器需要实现GlobalFilter接口
package com.atguigu.gateway.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class RtFilter implements GlobalFilter, Ordered {
// 过滤器逻辑
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request= exchange.getRequest();
ServerHttpResponse response= exchange.getResponse();
String uri=request.getURI().toString();
long start=System.currentTimeMillis();
log.info("请求【{}】开始:时间:{}",uri,start);
//========================以上是前置逻辑=========================
//异步调用,因此不能把后置逻辑直接放在代码后面
Mono<Void> filter = chain.filter(exchange)
.doFinally((result)->{
//=======================以下是后置逻辑=========================
long end = System.currentTimeMillis();
log.info("请求【{}】结束:时间:{},耗时:{}ms",uri,end,end-start);
}); //放行 10s
return filter;
}
//优先级
@Override
public int getOrder() {
return 0;
}
}
自定义网关过滤器
自定义网关过滤器需要继承AbstractNameValueGatewayFilterFactory
package com.atguigu.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.UUID;
@Component
public class OnceTokenGateWayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
String value = config.getValue();
if ("uuid".equalsIgnoreCase(value)){
value = UUID.randomUUID().toString();
}
if ("jwt".equalsIgnoreCase(value)){
value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
}
headers.add(config.getName(),value);
}));
}
};
}
}
修改配置文件
spring:
cloud:
gateway:
routes:
- id: order-route
uri: lb://service-order
predicates:
- name: Path
args:
patterns: /api/order/**
order: 1
filters:
- RewritePath=/api/order?(?<segment>.*), /$\{segment}
# 自定义过滤器,和断言一样,只保留GateWayFilterFactory之前的部分
- OnceToken=X-Response-Token,jwt