Heim  >  Artikel  >  Java  >  Einführung in die globalen Filter von Spring Cloud Gateway

Einführung in die globalen Filter von Spring Cloud Gateway

不言
不言nach vorne
2019-03-06 15:51:312715Durchsuche

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:

Einführung in die globalen Filter von Spring Cloud Gateway

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen