Home  >  Article  >  Java  >  Introduction to spring cloud gateway global filters

Introduction to spring cloud gateway global filters

不言
不言forward
2019-03-06 15:51:312716browse

This article brings you an introduction to the spring cloud gateway global filter. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Global filters act on all routes and do not need to be configured separately. We can use it to achieve many unified processing business requirements, such as authority authentication, IP access restrictions, etc.

Interface definition class: org.springframework.cloud.gateway.filter.GlobalFilter

public interface GlobalFilter {
    Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}</void>

There are many GlobalFilter implementation classes that come with gateway, as shown below:

Introduction to spring cloud gateway global filters

There are GlobalFilters related to forwarding, routing, load, etc. If you are interested, you can check out the source code to learn more.

How do we define GlobalFilter to implement our own business logic?

Give a case from the official document:

@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");
            }));
        };
    }
}

Three GlobalFilters are defined above, and the order of execution is specified through @Order. The smaller the number, the higher the priority. The following is the output log. You can see the order of execution from the log:

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

When the GlobalFilter has a lot of logic, I still recommend that you write a separate GlobalFilter to handle it. For example, we want to implement access restrictions on IP , the request will not be allowed if it is not in the IP whitelist.

For separate definition, you only need to implement the two interfaces GlobalFilter and 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>

There is nothing much to say about the use of filtering. It is relatively simple, but it is very useful and can handle many needs. The IP authentication interception mentioned above is just the tip of the iceberg. More functions need to be implemented by ourselves based on filters. accomplish.

For example, if I want to do a/b testing, I have to work on the routing and forwarding level. We posted a picture earlier. There are many default global filters in the picture, among which there is a LoadBalancerClientFilter that is responsible for selecting routes. The load filter of the service will select the forwarding service through loadBalancer, and then pass it to the following routing NettyRoutingFilter filter for execution, then we can implement it based on this mechanism.

The following method is used to pass data to the next Filter in Filter:

exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);

The acquirer obtains it directly:

URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);

If I want to change the routing, I can do this :

@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>

The order of LoadBalancerClientFilter is 10100, which is 1 larger than it here, so that the address to be routed can be replaced after it is executed.

The above is the detailed content of Introduction to spring cloud gateway global filters. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete