Maison > Java > javaDidacticiel > Introduction aux filtres globaux de Spring Cloud Gateway

Introduction aux filtres globaux de Spring Cloud Gateway

不言
Libérer: 2019-03-06 15:51:31
avant
2880 Les gens l'ont consulté

Cet article vous présente le filtre global Spring Cloud Gateway. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Les filtres globaux s'appliquent à toutes les routes et n'ont pas besoin d'être configurés séparément. Nous pouvons les utiliser pour répondre à de nombreuses exigences commerciales de traitement unifié, telles que l'authentification des autorités, les restrictions d'accès IP, etc.

Classe de définition d'interface : org.springframework.cloud.gateway.filter.GlobalFilter

public interface GlobalFilter {
    Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}</void>
Copier après la connexion

Il existe de nombreuses classes d'implémentation GlobalFilter fournies avec la passerelle, comme indiqué ci-dessous :

Introduction aux filtres globaux de Spring Cloud Gateway

Il existe des GlobalFilters liés au transfert, au routage, au chargement, etc. Si vous êtes intéressé, vous pouvez consulter le code source pour en savoir plus.

Comment définissons-nous GlobalFilter pour mettre en œuvre notre propre logique métier ?

Donnez un exemple tiré du document officiel :

@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");
            }));
        };
    }
}
Copier après la connexion

Trois GlobalFilters sont définis ci-dessus, et l'ordre d'exécution est spécifié via @Order. Plus le nombre est petit, plus la priorité est élevée. Voici le journal de sortie. Vous pouvez voir l'ordre d'exécution à partir du journal :

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
Copier après la connexion

Lorsque le GlobalFilter a beaucoup de logique, je vous recommande toujours d'écrire un GlobalFilter séparé pour le gérer. Par exemple, si nous souhaitons implémenter des restrictions d'accès IP, les requêtes qui ne figurent pas dans la liste blanche IP ne seront pas autorisées à être appelées.

Pour une définition séparée, il vous suffit d'implémenter les deux interfaces GlobalFilter et Ordered.

@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>
Copier après la connexion

Il n'y a rien à dire sur l'utilisation du filtrage. C'est relativement simple, mais il est très efficace et peut répondre à de nombreux besoins. L'interception d'authentification IP mentionnée ci-dessus n'est que la pointe de l'iceberg. Plus de fonctions doivent être basées sur le filtrage nous-mêmes du périphérique à mettre en œuvre.

Par exemple, si je veux faire des tests a/b, je dois alors travailler au niveau du routage et du transfert. Nous avons publié une image plus tôt. Il y a de nombreux filtres globaux par défaut dans l'image, parmi lesquels. est un LoadBalancerClientFilter qui est responsable de la sélection des routes. Le filtre de charge du service sélectionnera le service de transfert via LoadBalancer, puis le transmettra au filtre NettyRoutingFilter de routage suivant pour l'exécution, nous pourrons ensuite l'implémenter sur la base de ce mécanisme.

La méthode suivante est utilisée pour transmettre les données du Filtre au Filtre suivant :

exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
Copier après la connexion

L'acquéreur les obtient directement :

URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
Copier après la connexion

Si je souhaite modifier le routage, vous pouvez faire ceci :

@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>
Copier après la connexion

L'ordre de LoadBalancerClientFilter est 10100, soit 1 de plus qu'ici, afin que l'adresse à acheminer puisse être remplacée après son exécution.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal