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; // 设置一个标志位, 匹配上才能访问
    }

}

配置:

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
追风筝的人er6 天前
企业管理系统如何实现自定义首页与千人千面?RuoYi Office 给出了完整方案
vue.js·spring boot·spring cloud
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
坐吃山猪6 天前
OpenClaw04_Gateway常见问题
网络·gateway·openclaw
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习