• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Spring Cloud Gateway①入门以和自定义过滤器开发

武飞扬头像
太空眼睛
帮助1

本文开发环境介绍

开发依赖 版本
Spring Boot 2.7.0
Spring Cloud 2021.0.1
Spring Cloud Alibaba 2021.0.1.0

转发示例演示

启动Spring Cloud Gateway的最小依赖配置

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--引⼊webflux-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    </dependencies>

转发配置示例

以下是一个简单的转发的配置,把/百度的请求转发到https://www.百度.com

server:
  port: 8081
spring:
  application:
    name: demo-gateway
  cloud:
    gateway:
      #路由配置
      routes:
        - id: 百度
          uri: https://www.百度.com
          predicates:
            - Path=/百度
          filters:
            - StripPrefix=1

Spring Boot启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoGatewayApplication.class, args);
    }
}

程序启动

程序启动后输出以下日志,说明程序启动成功

Started DemoGatewayApplication in 16.408 seconds (JVM running for 19.345)

浏览器访问

在浏览器地址栏输入http://localhost:8081/百度
学新通

演示总结

Spring Cloud Gateway内置了多种过滤器,我们示例中演示了StripPrefix过滤器的使用,把原始请求/百度截断了,这样转发到http://localhost:8081/百度时才不会出现404错误

自定义过滤器

Spring Cloud Gateway虽然自带有许多实用的GatewayFilter FactoryGateway FilterGlobal Filter,但是在很多业务情景下仍然需要自定义过滤器,实现一些自定义操作,满足业务需求。所以自定义过滤器就显得非常有必要。本文分表介绍自定义Gateway Filter、自定义Global Filter、自定义Gateway Filter Factory

自定义Gateway Filter

实现自定义的Gateway Filter,需要实现GatewayFilterOrdered两个接口

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Slf4j
public class DemoGatewayFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.debug("this is GatewayFilter!");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // 数值越小,越先执行
        return 0;
    }
}

定义好DemoGatewayFilter以后,需要跟Route绑定使用,不能在application.yml文件中配置使用

@Configuration
public class FilterAutoConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes().route(r ->
                        r.path("/**")
                                .filters(gfs -> gfs.filters(new DemoGatewayFilter()))
                                .uri("https://www.百度.com"))
                .build();
    }
}

测试结果: 可以在控制台看到输出this is GatewayFilter!,但会报404,因为/百度的请求转发后最终请求的是https://www.百度.com/百度

自定义Gateway Filter Factory

很多时候更希望在配置文件中配置Gateway Filter, 像使用gateway内置的过滤器那样,所以可以自定义过滤器工厂实现。稍微改造下上面的DemoGatewayFilter

import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Slf4j
public class DemoGatewayFilter implements GatewayFilter, Ordered {

    private final Config config;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (!config.isEnabled()) {
            return chain.filter(exchange);
        }

        log.debug("this is DemoGatewayFilterFactory!");
        log.debug("args: {}, {}, {}", config.isEnabled(), config.getArg1(), config.getArg2());

        exchange.getAttributes().put("begin_time", System.currentTimeMillis());
        return chain.filter(exchange).then(
                Mono.fromRunnable(() -> {
                    Long beginTime = exchange.getAttribute("begin_time");
                    log.info("begin:{}, end:{}", beginTime, System.currentTimeMillis());
                })
        );
    }

    @Override
    public int getOrder() {
        // 数值越小,越先执行
        return 0;
    }

    @Data
    public static class Config {
        private boolean enabled;
        private String arg1;
        private String arg2;
    }
}

注释掉上面测试时绑定的Route

@Configuration
public class FilterAutoConfiguration {

//    @Bean
//    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
//        return builder.routes().route(r ->
//                        r.path("/**")
//                                .filters(gfs -> gfs.filters(new DemoGatewayFilter1()))
//                                .uri("https://www.百度.com"))
//                .build();
//    }
}

自定义过滤器工厂需要继承AbstractGatewayFilterFactory

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Slf4j
@Component
public class DemoGatewayFilterFactory extends AbstractGatewayFilterFactory<DemoGatewayFilter.Config> {

    public DemoGatewayFilterFactory() {
        super(DemoGatewayFilter.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        // yml配置文件中参数的赋值顺序
        return Arrays.asList("enabled", "arg1", "arg2");
    }

    @Override
    public GatewayFilter apply(DemoGatewayFilter.Config config) {
        return new DemoGatewayFilter(config);
    }
}

在application.yml配置使用

server:
  port: 8081
spring:
  application:
    name: demo-gateway
  cloud:
    gateway:
      #路由配置
      routes:
        - id: 百度
          uri: https://www.百度.com
          predicates:
            - Path=/百度
          filters:
            - StripPrefix=1
            - Demo=true,hello,world

测试结果: 控制台可以看到输出

this is DemoGatewayFilterFactory!
args: true, hello, world

自定义Global Filter

实现自定义全局过滤器需要实现GlobalFilterOrdered

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class DemoGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.debug("this is DemoGlobalFilter");
        return chain.filter(exchange);
    }

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

测试结果: 控制台可以看到输出
学新通

filter多种配置方式

同一种filter可以配置多次,配置方式也有多种,以下是不同方式的示例

server:
  port: 8081
spring:
  application:
    name: demo-gateway
  cloud:
    gateway:
      #路由配置
      routes:
        - id: 百度
          uri: https://www.百度.com
          predicates:
            - Path=/百度
          filters:
            - StripPrefix=1
            - Demo=true,hello,world
            - name: Demo
              args:
                enabled: true
                arg1: hello2
                arg2: world2

测试结果: 控制台可以看到输出
学新通

总结

示例演示了启动一个Spring Cloud Gateway需要的最小依赖,以及程序配置。通过自定义Filter可以满足我们个性化的业务需求,希望可以帮助大家快速基于Gateway二次开发

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfikfkb
系列文章
更多 icon
同类精品
更多 icon
继续加载