自学内容网 自学内容网

GateWay使用手册

好的,下面是优化后的版本。为了提高可读性和规范性,我对内容进行了结构化、简化了部分代码,同时增加了注释说明,便于理解。


1. 引入依赖

pom.xml 中添加以下依赖:

<dependencies>
    <!-- Spring Cloud Gateway:提供API网关功能 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!-- Spring Cloud Alibaba Nacos Discovery:用于服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- Spring Cloud Loadbalancer:提供客户端负载均衡 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>

2. 启动类 (GateApplication.java)

定义主启动类,启动 Spring Boot 应用:

@SpringBootApplication  // 标明这是Spring Boot应用的入口
public class GateApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateApplication.class, args);  // 启动应用
    }
}

3. 配置文件 (application.yml)

配置网关的基本设置、Nacos 服务发现以及路由规则。

server:
  port: 8080  # 配置网关监听的端口

spring:
  application:
    name: gateway  # 应用名称,用于 Nacos 等服务发现

  cloud:
    nacos:
      discovery:
        server-addr: xiaotianlong.xyz:8848  # 配置 Nacos 服务器地址

    gateway:
      routes:  # 配置网关的路由规则
        # 路由规则 1
        - id: service_name  # 路由的唯一ID
          uri: lb://service_name  # 使用负载均衡访问注册到 Nacos 中的服务
          predicates:
            - Path=/user/**  # 请求路径以 `/user/` 开头时触发此路由
          filters:
            - AddRequestHeader=X-Request-Foo, Bar  # 添加请求头

        # 路由规则 2
        - id: service_name2
          uri: lb://service_name2
          predicates:
            - Path=/order/**  # 请求路径以 `/order/` 开头时触发此路由

4. 自定义全局过滤器

定义一个全局过滤器,记录请求的时间并打印日志。

@Component  // 声明为Spring组件
public class MyGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 记录请求开始时间
        System.out.println("请求开始时间: " + System.currentTimeMillis());
        
        // 放行请求
        return chain.filter(exchange)
                .then(Mono.fromRunnable(() -> {
                    // 记录请求结束时间
                    System.out.println("请求结束时间: " + System.currentTimeMillis());
                }));
    }

    @Override
    public int getOrder() {
        // 过滤器的执行顺序,数字越小优先级越高
        return 0;
    }
}

5. 自定义Gateway过滤器

创建一个自定义的 Gateway 过滤器工厂,允许动态配置过滤器的参数。

@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {

    // 内部配置类,允许用户配置过滤器的参数
    @Data
    public static class Config {
        private String pattern = "yyyy-MM-dd";  // 设置默认日期格式
        private String message = "默认日志信息";  // 自定义日志信息
    }

    public MyGatewayFilterFactory() {
        super(Config.class);  // 指定配置类类型
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return List.of("pattern", "message");  // 设置快捷字段顺序
    }

    @Override
    public GatewayFilter apply(Config config) {
        // 创建过滤器逻辑
        return new OrderedGatewayFilter((exchange, chain) -> {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(config.getPattern());
            System.out.println("请求开始时间: " + formatter.format(LocalDateTime.now()));
            System.out.println(config.getMessage());  // 打印自定义日志信息
            return chain.filter(exchange)
                    .then(Mono.fromRunnable(() -> {
                        System.out.println("请求结束时间: " + formatter.format(LocalDateTime.now()));
                    }));
        }, 1);//在这里设置顺序
    }
}

6. 配置自定义过滤器

application.yml 文件中配置自定义的 MyGatewayFilterFactory 过滤器,使其生效:

spring:
  cloud:
    gateway:
      routes:
        - id: example_route
          uri: lb://some-service
          predicates:
            - Path=/somepath/**  # 路径匹配条件
          filters:
            - name: My  # 使用自定义过滤器
              args:
                pattern: "yyyy-MM-dd~HH:mm:ss"  # 自定义日期格式
                message: "这是一个统计时间的gateway过滤器"  # 自定义日志信息

或者

spring:
  cloud:
    gateway:
      routes:
        - id: example_route
          uri: lb://some-service
          predicates:
            - Path=/somepath/**  # 路径匹配条件
          filters:
             # 由于设置了shortcutfieldorder,所以可以这样写
            - My="yyyy-MM-dd~HH:mm:ss", "这是一个统计时间的gateway过滤器"

7.案例:登录检验

@Component
@EnableConfigurationProperties(AuthProperties.class)
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Resource
    private AuthProperties authProperties;
    @Resource
    private JwtTool jwtTool;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取request
        ServerHttpRequest request = exchange.getRequest();
        //2.判断路径是否需做登录拦截
        List<String> excludePaths = authProperties.getExcludePaths();
        if (isExclude(request.getPath())) {
            //此时不需要拦截,直接放行
            return chain.filter(exchange);
        }
        //3.获得token
        String token = request.getHeaders().getFirst("authorization");
        //4.检验并解析token
        Long userId = null;
        try {
            userId = jwtTool.parseToken(token);
        } catch (Exception e) {
            //设置响应状态码为401
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //拦截
            return response.setComplete();
        }
        //todo 5.传递用户信息

        //6.放行
        return chain.filter(exchange);
    }

    private boolean isExclude(RequestPath path) {
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String pattern : excludePaths) {
            if (antPathMatcher.match(pattern, path.toString())) {
                return true;
            }
        }
        return false;
    }

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


原文地址:https://blog.csdn.net/qq_42798343/article/details/144096542

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!