Dieser Artikel bietet Ihnen eine Einführung in den globalen Filter von Spring Cloud Gateway. Ich hoffe, dass er für Freunde hilfreich ist.
Globale Filter gelten für alle Routen und müssen nicht separat konfiguriert werden. Wir können damit viele einheitliche Geschäftsanforderungen wie Autoritätsauthentifizierung, IP-Zugriffsbeschränkungen usw. erreichen.
Schnittstellendefinitionsklasse: org.springframework.cloud.gateway.filter.GlobalFilter
public interface GlobalFilter { Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }</void>
Es gibt viele GlobalFilter-Implementierungsklassen, die mit Gateway geliefert werden, wie unten gezeigt:
Es gibt GlobalFilter im Zusammenhang mit Weiterleitung, Routing, Laden usw. Wenn Sie interessiert sind, können Sie sich den Quellcode ansehen, um mehr zu erfahren.
Wie definieren wir GlobalFilter, um unsere eigene Geschäftslogik zu implementieren?
Geben Sie ein Beispiel aus dem offiziellen Dokument:
@Configuration public class ExampleConfiguration { private Logger log = LoggerFactory.getLogger(ExampleConfiguration.class); @Bean @Order(-1) public GlobalFilter a() { return (exchange, chain) -> { log.info("first pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("third post filter"); })); }; } @Bean @Order(0) public GlobalFilter b() { return (exchange, chain) -> { log.info("second pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("second post filter"); })); }; } @Bean @Order(1) public GlobalFilter c() { return (exchange, chain) -> { log.info("third pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("first post filter"); })); }; } }
Oben sind drei GlobalFilter definiert, und die Ausführungsreihenfolge wird durch @Order angegeben. Je kleiner die Zahl, desto höher die Priorität. Das Folgende ist das Ausgabeprotokoll. Aus dem Protokoll können Sie die Ausführungsreihenfolge ersehen:
2018-10-14 12:08:52.406 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : first pre filter 2018-10-14 12:08:52.406 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : second pre filter 2018-10-14 12:08:52.407 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : third pre filter 2018-10-14 12:08:52.437 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : first post filter 2018-10-14 12:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : second post filter 2018-10-14 12:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : third post filter
Wenn der GlobalFilter viel Logik hat, empfehle ich Ihnen dennoch, einen separaten GlobalFilter zu schreiben, um ihn zu verarbeiten Wenn wir Zugriffsbeschränkungen für IP implementieren möchten, wird die Anfrage nicht zugelassen, wenn sie nicht in der IP-Whitelist enthalten ist.
Zur separaten Definition müssen Sie lediglich die beiden Schnittstellen GlobalFilter und Ordered implementieren.
@Component public class IPCheckFilter implements GlobalFilter, Ordered { @Override public int getOrder() { return 0; } @Override public Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { HttpHeaders headers = exchange.getRequest().getHeaders(); // 此处写死了,演示用,实际中需要采取配置的方式 if (getIp(headers).equals("127.0.0.1")) { ServerHttpResponse response = exchange.getResponse(); ResponseData data = new ResponseData(); data.setCode(401); data.setMessage("非法请求"); byte[] datas = JsonUtils.toJson(data).getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(datas); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); return response.writeWith(Mono.just(buffer)); } return chain.filter(exchange); } // 这边从请求头中获取用户的实际IP,根据Nginx转发的请求头获取 private String getIp(HttpHeaders headers) { return "127.0.0.1"; } }</void>> Zur Verwendung der Filterung gibt es nicht viel zu sagen. Sie ist relativ einfach, aber sehr nützlich. Die oben erwähnte IP-Authentifizierung ist nur die Spitze des Eisbergs auf Basis von Filtern umzusetzen. Wenn ich zum Beispiel A/B-Tests durchführen möchte, muss ich auf der Routing- und Weiterleitungsebene arbeiten. Wir haben zuvor ein Bild gepostet, darunter dort ist ein LoadBalancerClientFilter, der für die Auswahl von Routen verantwortlich ist. Der Lastfilter des Dienstes wählt den Weiterleitungsdienst über LoadBalancer aus und übergibt ihn dann zur Ausführung an den folgenden Routing-NettyRoutingFilter-Filter. Anschließend können wir ihn basierend auf diesem Mechanismus implementieren. Filter übergibt Daten auf folgende Weise an den nächsten Filter:
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);Der Acquirer erhält sie direkt:
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);Wenn ich das Routing ändern möchte, kann ich dies tun :
@Component public class DebugFilter implements GlobalFilter, Ordered { @Override public int getOrder() { return 10101; } @Override public Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { try { exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, new URI("http://192.168.31.245:8081/house/hello2")); } catch (URISyntaxException e) { e.printStackTrace(); } return chain.filter(exchange); } }</void>Die Reihenfolge von LoadBalancerClientFilter ist 10100, also 1 größer als hier, sodass die zu routende Adresse nach der Ausführung ersetzt werden kann.
Das obige ist der detaillierte Inhalt vonEinführung in die globalen Filter von Spring Cloud Gateway. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!