Spring Cloud Gateway 自定義Filter


Spring Cloud Gateway 的自定義Filter分為GatewayFilter局部過濾器和GlobalFilter全局過濾器

GatewayFilter : 需要通過spring.cloud.routes.filters 配置在具體路由下,只作用在當前路由上或通過spring.cloud.default-filters配置在全局,作用在所有路由上

GlobalFilter : 全局過濾器,不需要在配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain可識別的過濾器

GatewayFilter局部過濾器

自定義局部過濾器需要實現GatewayFilterOrdered 兩個接口

@Slf4j
public class CostomerGatewayFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("自定義局部過濾器:{}====================", "CustomerGatewayFilter");
        return chain.filter(exchange);
    }

    /**
     * 值越小,優先級越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

在配置文件中使用自定義局部過濾器還需要使用自定義過濾器工廠來包裝
這里的后綴GatewayFilterFactory不能寫錯,因為配置文件中配置的自定義過濾器名就是自定義過濾器工廠的類名去掉GatewayFilterFactory后綴的名字
把后綴寫錯了項目啟動的時候就會報錯說找不到這個自定義過濾器

public class CustomerGatewayFilterFactory extends AbstractGatewayFilterFactory {
    @Override
    public GatewayFilter apply(Object config) {
        return new CostomerGatewayFilter();
    }
}

在配置類中將自定義過濾器工廠注冊到容器中,當然也可以在自定義過濾器工廠類上加@Component注解

@Configuration
public class GatewayConfig {

    @Bean
    public CustomerGatewayFilterFactory myGatewayFilterFactory() {
        return new CustomerGatewayFilterFactory();
    }

}

在配置文件中配置自定義過濾器,這里的Customer就是自定義過濾器工廠類名去掉GatewayFilterFactory后綴的名字

spring:
  application:
    name: service-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: service-provider
          uri: lb://service-provider
          predicates:
            - Path=/provider/**
          filters:
            - Customer

GlobalFilter全局過濾器

自定義全局過濾器需要實現 GlobalFilterOrdered 接口

@Slf4j
public class LoginFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        String token = request.getHeaders().getFirst("token");
        log.info("訪問的路徑:{}", path);
        log.info("token: {}==================", token);

        if (token == null) {
            ServerHttpResponse response = exchange.getResponse();
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            ResponseData responseData = new ResponseData(401, "請登錄");
            String res = null;
            try {
                res = new ObjectMapper().writeValueAsString(responseData);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            DataBuffer wrap = response.bufferFactory().wrap(res.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(wrap));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

在配置類中注冊全局過濾器,這樣這個全局過濾器就是全局過濾了

@Configuration
public class GatewayConfig {

    @Bean
    public GlobalFilter loginFilter() {
        return new LoginFilter();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM