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

}

配置:

相关推荐
枫叶200010 分钟前
OceanBase数据库-学习笔记1-概论
数据库·笔记·学习·oceanbase
你可以叫我仔哥呀30 分钟前
k8s学习记录(五):Pod亲和性详解
学习·容器·kubernetes
RaLi和夕41 分钟前
单片机学习笔记9.数码管
汇编·笔记·单片机·嵌入式硬件·学习
见青..1 小时前
【学习笔记】文件包含漏洞--本地远程包含、伪协议、加密编码
前端·笔记·学习·web安全·文件包含
星雨流星天的笔记本1 小时前
1、Linux操作系统下,ubuntu22.04版本切换中英文界面
linux·学习
普普通通的一名码农2 小时前
ESP32-S3 入门学习笔记(四):LED实验
笔记·单片机·学习
一只码代码的章鱼2 小时前
学习笔记2(Lombok+算法)
笔记·学习·算法
虾球xz3 小时前
游戏引擎学习第247天:简化DEBUG_VALUE
c++·学习·游戏引擎
mask哥4 小时前
详解最新链路追踪skywalking框架介绍、架构、环境本地部署&配置、整合微服务springcloudalibaba 、日志收集、自定义链路追踪、告警等
java·spring cloud·架构·gateway·springboot·skywalking·链路追踪
superior tigre4 小时前
C++学习:六个月从基础到就业——模板编程:模板特化
开发语言·c++·学习