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>
Il existe de nombreuses classes d'implémentation GlobalFilter fournies avec la passerelle, comme indiqué ci-dessous :
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"); })); }; } }
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
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>
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);
L'acquéreur les obtient directement :
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
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>
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!