006-spring cloud alibaba之gateway网关-过滤器Filter

gateway过滤器

过滤器作用在路由内部,体现在配置上就是Filter配置在routes下面。比如

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user
          uri: lb://user
          predicates:
            - Path=/cjxz/**
            - After=2026-01-10T21:40:10.529+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1 # 去掉第一个路径:/cjxz/

上面的filters就是一个过滤器。过滤器的作用就是允许修改传入HTTP请求或者传出HTTP响应。大白话就是filters可以修改http的入参,也可以修改http出参。gateway自带很多过滤器。比如上面使用StripPrefix就是其中一个,作用就是去掉路径中的第一个参数。下面举几个自带的过滤器使用。更多的过滤器可以去官网阅读一下,了解大概有哪些过滤器。在实际应用中遇到在去学习也可以。

RequestSize请求大小的过滤器

RequestSize的配置

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user
          uri: lb://user
          predicates:
            - Path=/cjxz/**
            - After=2026-01-10T21:40:10.529+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1 # 去掉第一个路径:/cjxz/
            - name: RequestSize
              args:
                maxSize:5000

测试方法

less 复制代码
@PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "请选择要上传的文件";
        }

        try {
            // 创建上传目录(如果不存在)
            Path uploadPath = Paths.get(UPLOAD_DIR);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成唯一文件名,防止覆盖
            String originalFilename = file.getOriginalFilename();
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String uniqueFilename = UUID.randomUUID().toString() + fileExtension;

            // 保存文件
            Path filePath = uploadPath.resolve(uniqueFilename);
            Files.copy(file.getInputStream(), filePath);

            return String.format("文件上传成功!\n" +
                            "原始文件名:%s\n" +
                            "保存文件名:%s\n" +
                            "文件大小:%d bytes\n" +
                            "保存路径:%s",
                    originalFilename,
                    uniqueFilename,
                    file.getSize(),
                    filePath.toAbsolutePath().toString());

        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败:" + e.getMessage();
        }
    }

测试

调用接口,上传一个较大的文件提示错误

vbscript 复制代码
413Payload Too Large请求体过大
请求内容过大,服务器无法处理
Request size is larger than permissible limit. Request size is 13.5 MB where permissible limit is 5.0 kB

AddRequestHeader过滤器

使用配置

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user
          uri: lb://user
          predicates:
            - Path=/cjxz/**
            - After=2026-01-10T21:40:10.529+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1 # 去掉第一个路径:/cjxz/
            - name: RequestSize
              args:
                maxSize:5000
            - AddRequestHeader=X-Request-red, blue

请求localhost:9999/cjxz/hello转发到user服务中,会增加RequestHeader参数:X-Request-red=blue

自定义过滤器

自定义过滤器需要实现GlobalFilter和Ordered。下面是自定义过滤器的例子

java 复制代码
@Component
public class MyFilter implements GlobalFilter, Ordered {
    // 拦截器执行顺序,返回的int越小,在拦截器链路中越靠前
    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("进入过滤器..");
        String userName = exchange.getRequest().getQueryParams().getFirst("userName");
        if(StringUtils.hasLength(userName)){
            return chain.filter(exchange);
        }
        // 没有userName直接结束
        System.out.println("非法请求...");
        exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
        return exchange.getResponse().setComplete();
    }
}

验证结果。访问:localhost:9999/cjxz/hello,不携带参数。

复制代码
406Not Acceptable不可接受
服务器在进行"服务器驱动的内容协商"后,找不到任何相关内容

带参数访问

css 复制代码
curl --location --request GET 'localhost:9999/cjxz/hello?userName=112' \
--header 'reqId: 8786768786767878'

响应结果

复制代码
hello xxx ...9002
相关推荐
每天一道题5 小时前
CAP、Raft 与多数派:分布式系统如何达成一致?
分布式·后端·微服务
火22516 小时前
# C++ 微服务即时通讯系统(四):MySQL、Redis 与 Elasticsearch——数据分工与一致性
c++·mysql·微服务
我不会起名字3222 天前
服务注册了却调不通:注册中心与心跳的 3 个时间参数
微服务·nacos·注册中心·排查
知已难寻2 天前
第 5 篇 · 云原生生态与实践:微服务、DevOps、可观测性与 Serverless
大数据·linux·服务器·微服务·云原生·云计算·devops
利威尔xu2 天前
Go IM 源码实战(7):断线三天重连,水位算错就漏消息
redis·后端·微服务·面试·golang
pt10432 天前
Cisco设备网络安全系列-16:微服务、Kubernetes与无服务器架构安全
网络·安全·微服务·架构
阿里云云原生2 天前
LiteLLM 半年两度被投毒,大模型的“钥匙串”该放在哪里?
微服务·serverless
喵了几个咪2 天前
GoWind ShortPlay 拆解:不用模型的推荐闭环——埋点回流、三路召回与已看去重
开发语言·后端·微服务·golang·gowind
喵了几个咪2 天前
GoWind UBA 拆解:把 Doris UNIQUE KEY 翻译成 ClickHouse——读数正确性对齐实录
开发语言·后端·clickhouse·微服务·golang·gowind