SpringCloud之Gateway网关过滤器filter

1、gateway-filter 网关服务-过滤器

SpringCloud之Gateway网关过滤器filter_第1张图片

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.yzm</groupId>
        <artifactId>springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>gateway-filter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>gateway-filter</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
@EnableEurekaClient
@SpringBootApplication
public class GatewayFilterApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayFilterApplication.class, args);
    }
}
server:
  port: 8025

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8088/eureka/

spring:
  application:
    name: gateway-filter
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true

2、常用内置过滤器

AddRequestHeader 添加请求头信息

spring:
  cloud:
    gateway:
		routes:
	        - id: addrh_test
	          uri: http://httpbin.org:80
	          predicates:
	            - Path=/get
	          filters:
	            - AddRequestHeader=X-Request-Foo, Req

请求:localhost:8025/get,经网关后会额外添加X-Request-Foo:Req键值对的请求头信息再转发到下游服务器
SpringCloud之Gateway网关过滤器filter_第2张图片
SpringCloud之Gateway网关过滤器filter_第3张图片

RemoveRequestHeader 移除请求头信息

          filters:
            - AddRequestHeader=X-Request-Foo, Req
			- RemoveRequestHeader=User-Agent

SpringCloud之Gateway网关过滤器filter_第4张图片

SetRequestHeader 替换请求头信息(没有就添加)

          filters:
            - SetRequestHeader=X-Request-Foo, Req
            - SetRequestHeader=X-Forwarded-Host, location:test

SpringCloud之Gateway网关过滤器filter_第5张图片

AddRequestParameter 添加请求参数

          filters:
            - AddRequestParameter=age, 22 

SpringCloud之Gateway网关过滤器filter_第6张图片

RemoveRequestParameter 删除请求参数

          filters:
            - RemoveRequestParameter=age

AddResponseHeader 添加响应头信息

          filters:
            - AddRequestHeader=X-Request-Foo, Req
            - AddResponseHeader=X-Response-Foo, Res

SpringCloud之Gateway网关过滤器filter_第7张图片

RemoveResponseHeader 删除响应头信息

          filters:
            - RemoveResponseHeader=X-Response-Foo, Res

SpringCloud之Gateway网关过滤器filter_第8张图片

SetResponseHeader 替换响应头信息(没有就添加)

          filters:
            - SetResponseHeader=X-Response-Foo, Res

SetStatus 设置响应的 HTTP 状态

          filters:
            - SetStatus=401

SpringCloud之Gateway网关过滤器filter_第9张图片

StripPrefix 截取路径位

		routes:
	        - id: strp_test
	          uri: http://httpbin.org:80
	          predicates:
	            - Path=/a/b/get
	          filters:
	            - StripPrefix=2

SpringCloud之Gateway网关过滤器filter_第10张图片

PrefixPath 添加前缀路径

		routes:
	        - id: prep_test
	          uri: http://httpbin.org:80
	          predicates:
	            - Path=/utf8
	          filters:
	            - PrefixPath=/encoding

SpringCloud之Gateway网关过滤器filter_第11张图片

RedirectTo 重定向

	routes:
        - id: redirect_test
          uri: http://httpbin.org:80
          filters:
            - RedirectTo=302, https://www.baidu.com

第一个参数是status,必须是300系列的重定向 HTTP 代码
第二个参数是url,跳转地址,会放在响应的Location的header中
SpringCloud之Gateway网关过滤器filter_第12张图片

RewritePath 重写路径

	routes:
        - id: rewp_test
          uri: http://httpbin.org:80
          predicates:
            - Path=/yzm/**
          filters:
            - RewritePath=/yzm/?(?.*), /$\{segment}

SpringCloud之Gateway网关过滤器filter_第13张图片

SetPath 设置路径

	routes:
        - id: setp_test
          uri: http://httpbin.org:80
          predicates:
            - Path=/y/zm/{segment}
          filters:
            - SetPath=/{segment}

SpringCloud之Gateway网关过滤器filter_第14张图片

RequestSize 请求数据大小

      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

maxSize是一种DataSize类型,因此可以将值定义为一个数字,后跟一个可选的DataUnit后缀,例如“KB”或“MB”。字节的默认值为“B”,大小为 5 MB。

3、自定义过滤器

自定义过滤器需要实现 GatewayFilter 和 Ordered 接口。
该过滤器:计算请求过程消耗的时间

@Slf4j
public class MyGatewayFilter implements GatewayFilter, Ordered {

    private static final String TIME_BEGIN = "timeBegin";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //请求执行前
        exchange.getAttributes().put(TIME_BEGIN, System.currentTimeMillis());

        //请求执行后
        return chain.filter(exchange).then(
                Mono.fromRunnable(() -> {
                    Long startTime = exchange.getAttribute(TIME_BEGIN);
                    if (startTime != null) {
                        log.info(exchange.getRequest().getURI().getRawPath() + ": "
                                + (System.currentTimeMillis() - startTime) + "ms");
                    }
                })
        );
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

通过java代码制定路由规则

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r
                        .path("/get")
                        .filters(f -> f
                                .filter(new MyGatewayFilter())
                                .addRequestHeader("addRequest", "yzm")
                                .addResponseHeader("addResponse", "yzm"))
                        .uri("http://httpbin.org:80")
                        .id("myFilterTest")
                )
                .build();
    }
}

SpringCloud之Gateway网关过滤器filter_第15张图片
在这里插入图片描述

4、自定义过滤器工厂

package com.yzm.gatewayfilter.filter;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.style.ToStringCreator;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * 自定义过滤器工厂
 */
@Slf4j
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.NameConfig> {

    private static final String TIME_BEGIN = "timeBegin";
    private static final String KEY = "withParams";

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(KEY);
    }

    public MyGatewayFilterFactory() {
        super(NameConfig.class);
    }

    @Override
    public GatewayFilter apply(NameConfig config) {
        return (exchange, chain) -> {
            exchange.getAttributes().put(TIME_BEGIN, System.currentTimeMillis());
            return chain.filter(exchange).then(
                    Mono.fromRunnable(() -> {
                        Long startTime = exchange.getAttribute(TIME_BEGIN);
                        if (startTime != null) {
                            StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath())
                                    .append(": ")
                                    .append(System.currentTimeMillis() - startTime)
                                    .append("ms");
                            if (config.isWithParams()) {
                                sb.append(" params:").append(exchange.getRequest().getQueryParams());
                            }
                            log.info(sb.toString());
                        }
                    })
            );
        };
    }

    @Data
    static class NameConfig {

        private boolean withParams;

        boolean isWithParams() {
            return withParams;
        }
    }

    public static class NameValueConfig {
        private String name;
        private String value;

        public NameValueConfig() {
        }

        public String getName() {
            return this.name;
        }

        public MyGatewayFilterFactory.NameValueConfig setName(String name) {
            this.name = name;
            return this;
        }

        public String getValue() {
            return this.value;
        }

        public MyGatewayFilterFactory.NameValueConfig setValue(String value) {
            this.value = value;
            return this;
        }

        public String toString() {
            return (new ToStringCreator(this)).append("name", this.name).append("value", this.value).toString();
        }
    }

}
spring:
  application:
    name: gateway-filter
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      routes:
        - id: myFactory_test
          uri: http://httpbin.org:80
          predicates:
            - Path=/factory/get
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request, Yzm
            # MyGatewayFilterFactory 过滤器工厂不需要写全名,前缀即可
            - My=false

SpringCloud之Gateway网关过滤器filter_第16张图片
上面的配置方式是对单一路由规则起效,下面的配置可以对所有路由有效

spring:
  application:
    name: gateway-filter
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      default-filters:
        - My=false
      routes:
        - id: myFactory_test
          uri: http://httpbin.org:80
          predicates:
            - Path=/factory/get
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request, Yzm
#            - My=false

5、全局过滤器

全局过滤器需要实现GlobalFilter接口。
该过滤器:要求访问必须携带请求参数token

package com.yzm.gatewayfilter.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 自定义全局过滤器
 * 测试:请求接口时需要带有 token 参数
 */
@Component
public class MyTokenFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
spring:
  application:
    name: gateway-filter
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      default-filters:
        - My=true
      routes:
        - id: myFactory_test
          uri: http://httpbin.org:80
          predicates:
            - Path=/factory/get
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request, Yzm
#            - My=false

不带token
SpringCloud之Gateway网关过滤器filter_第17张图片
带token
SpringCloud之Gateway网关过滤器filter_第18张图片

相关链接

首页
上一篇:Gateway路由、断言
下一篇:Gateway熔断、限流

你可能感兴趣的:(spring,cloud,spring,cloud)