SpringCloud学习(9)-GateWay网关-自定义拦截器

GateWay Filter详细配置说明

gateway Filter官网:Spring Cloud Gateway

作用:
  • 请求鉴权
  • 异常处理
  • 记录接口调用时长统计
过滤器类别
  • 全局默认过滤器:官网:Spring Cloud Gateway,出厂默认已有的,直接用,作用于所有的路由,不推荐。
  • 单一内置过滤器:官网:Spring Cloud Gateway,也可以称为网关过滤器,这种过滤器主要是作用于单一路由或者某个路由分组
  • 自定义过滤器
过滤器配置详解
常见内置过滤器

增删改请求头响应头

复制代码
 spring:
  cloud:
   gateway:
      routes:
        - id: pay_routh1 #pay_routh1                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001                #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service                #匹配后提供服务的路由地址
          predicates:
            - Path=/pay/gateway/get/**              # 断言,路径相匹配的进行路由
          filters:
            - AddRequestHeader=X-Request-username,value  # 请求头kv,若一头含有多参则重写一行设置
            - RemoveRequestHeader=sec-fetch-site  # 删除请求头sec-fetch-site
            - SetRequestHeader=sec-fetch-mode, Blue-updatebyzzyy # 将请求头sec-fetch-mode对应的值修改为Blue-updatebyzzyy
            - AddRequestParameter=customerId,9527001 # 新增请求参数Parameter:k ,v
            - RemoveRequestParameter=customerName   # 删除url请求参数customerName,你传递过来也是null
            - AddResponseHeader=X-Response-hello, BlueResponse # 新增响应参数X-Response-atguigu并设值为BlueResponse
            - SetResponseHeader=Date,2099-11-11 # 设置回应头Date值为2099-11-11
            - RemoveResponseHeader=Content-Type # 将默认自带Content-Type回应属性删除

对微服务路径和前缀进行配置:前缀修改

复制代码
 spring:
  cloud:
   gateway:
      routes:
        - id: pay_routh1 #pay_routh1                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001                #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service                #匹配后提供服务的路由地址
          predicates:
           #- Path=/pay/gateway/filter/**   # 被分拆为: PrefixPath + Path

            - Path=/gateway/filter/**              # 断言,为配合PrefixPath测试过滤,暂时注释掉/pay 
          filters:
            - PrefixPath=/pay # http://localhost:9527/pay/gateway/filter

路径修改

复制代码
 spring:
  cloud:
   gateway:
      routes:
        - id: pay_routh1 #pay_routh1                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001                #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service                #匹配后提供服务的路由地址
          predicates:
           #- Path=/pay/gateway/filter/**   # 被分拆为: PrefixPath + Path

            - Path=/XYZ/abc/{segment}              # 断言,为配合SetPath测试,{segment}的内容最后被SetPath取代
          filters:
            - SetPath=/pay/gateway/{segment}  # {segment}表示占位符,你写abc也行但要上下一致

重定向

复制代码
spring:
  cloud:
   gateway:
      routes:
        - id: pay_routh1 #pay_routh1                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001                #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service                #匹配后提供服务的路由地址
          predicates:
           - Path=/gateway/filter/**              # 断言,为配合PrefixPath测试过滤,暂时注释掉/pay 
          filters:
            - RedirectTo=302, http://www.baidu.com/ # 访问

自定义过滤器:自定义全局过滤器获取接口耗时(不用配置,默认全局生效)

java 复制代码
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;
/**
 * @author sun
 * @date 2024/4/1
 */
@Slf4j
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    public static final String START_VISIT_TIME = "startVisitTime";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(START_VISIT_TIME, System.currentTimeMillis());
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            Long startVisitTime = exchange.getAttribute(START_VISIT_TIME);
            if (startVisitTime != null) {
                long endVisitTime = System.currentTimeMillis();
                log.info("=================================================");
                log.info("访问接口主机: {}", exchange.getRequest().getURI().getHost());
                log.info("访问接口端口: {}", exchange.getRequest().getURI().getPort());
                log.info("访问接口URL: {}", exchange.getRequest().getURI().getPath());
                log.info("访问接口参数: {}", exchange.getRequest().getURI().getRawQuery());
                log.info("访问接口耗时: {}ms", (endVisitTime - startVisitTime));
                log.info("=================================================");
            }
        }));
    }

    // 数字越小优先级越高
    @Override
    public int getOrder() {
        return -1;
    }
}

自定义过滤器:自定义单一过滤器(需要在配置文件设置)

java 复制代码
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author sun
 * @date 2024/4/1
 */
@Slf4j
@Component
public class CustomSingleGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomSingleGatewayFilterFactory.Config> {

    public CustomSingleGatewayFilterFactory() {
        super(CustomSingleGatewayFilterFactory.Config.class);
    }

    @Override
    public GatewayFilter apply(CustomSingleGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            log.info("进入单一的过滤器 status: {}", config.getStatus());
            ServerHttpRequest request = exchange.getRequest();
            if (request.getQueryParams().containsKey(config.getStatus())) {
                return chain.filter(exchange);
            }
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return List.of("status");
    }

    @Getter
    @Setter
    public static class Config {
        private String status; // 设置一个标志位, 匹配上才能访问
    }

}

配置:

相关推荐
俊俊谢10 分钟前
【序章】金融量化入门级学习——暨一颗韭菜的茁壮成长
学习·金融
Ro Jace13 分钟前
“透彻式学习”与“渗透式学习”
学习
✎ ﹏梦醒͜ღ҉繁华落℘1 小时前
freeRTOS学习笔记(十二)--信号量
笔记·学习
野老杂谈3 小时前
如何快速学习智能合约开发语言 Solidity
开发语言·学习·智能合约·solidity·以太坊·区块链开发
Han.miracle3 小时前
Java线程的学习—多线程(一)
java·开发语言·学习
忧郁奔向冷的天3 小时前
视觉SLAM十四讲2nd—学习笔记(二)20250817
笔记·学习
阿琦学代码3 小时前
Spring Cloud(微服务) 概述
后端·spring·spring cloud
立志成为大牛的小牛4 小时前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
.柒宇.4 小时前
《云岚到家》第一章个人总结
spring boot·spring·spring cloud
Every exam must be5 小时前
10.27 JS学习12
开发语言·javascript·学习