菜单
本页目录

过滤器

基本使用

以重写过滤器为例

spring:
  cloud:
    gateway:
      routes:
        - id: order-route
          uri: lb://service-order
          predicates:
            - name: Path
              args:
                patterns: /api/order/**
          order: 1
          filters:
            - RewritePath=/api/order?(?<segment>.*), /$\{segment}

例如/api/order/readDb则会被重写为/readDb并转发给service-order服务 其他过滤器用法也基本一致,可以查阅官网 https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories.html

默认过滤器

若想让过滤作用在每一个路由上,则需要使用默认过滤器 例如,向响应头添加自定义标头过滤器

      default-filters:
        - AddResponseHeader=X-Response-Abc, 123

default-filters要与routes同级

全局过滤器

全局过滤器和默认过滤器都可以对所有的路由生效,但全局过滤器优先级更高 自定义全局过滤器需要实现GlobalFilter接口

package com.atguigu.gateway.filter;

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.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class RtFilter implements GlobalFilter, Ordered {
// 过滤器逻辑
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request=  exchange.getRequest();
        ServerHttpResponse response=  exchange.getResponse();
        String uri=request.getURI().toString();
        long start=System.currentTimeMillis();
        log.info("请求【{}】开始:时间:{}",uri,start);
        //========================以上是前置逻辑=========================
        //异步调用,因此不能把后置逻辑直接放在代码后面
        Mono<Void> filter = chain.filter(exchange)
                .doFinally((result)->{
                    //=======================以下是后置逻辑=========================
                    long end = System.currentTimeMillis();
                    log.info("请求【{}】结束:时间:{},耗时:{}ms",uri,end,end-start);
                }); //放行   10s



        return filter;
    }
    //优先级
    @Override
    public int getOrder() {
        return 0;
    }
}

自定义网关过滤器

自定义网关过滤器需要继承AbstractNameValueGatewayFilterFactory

package com.atguigu.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.UUID;
@Component
public class OnceTokenGateWayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                    ServerHttpResponse response = exchange.getResponse();
                    HttpHeaders headers = response.getHeaders();
                    String value = config.getValue();
                    if ("uuid".equalsIgnoreCase(value)){
                        value = UUID.randomUUID().toString();
                    }

                    if ("jwt".equalsIgnoreCase(value)){
                        value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
                    }

                    headers.add(config.getName(),value);
                }));

            }
        };
    }
}

修改配置文件

spring:
  cloud:
    gateway:
      routes:
        - id: order-route
          uri: lb://service-order
          predicates:
            - name: Path
              args:
                patterns: /api/order/**
          order: 1
          filters:
            - RewritePath=/api/order?(?<segment>.*), /$\{segment}
# 自定义过滤器,和断言一样,只保留GateWayFilterFactory之前的部分
            - OnceToken=X-Response-Token,jwt