13.gateway

一、使用

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>Spring-Cloud-Test</artifactId>
        <groupId>cn.luoruiyuan</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!--  热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--  nacos  -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

    </dependencies>

</project>

2.配置编写

server:
  port: 9000

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        password: nacos
        username: nacos
        server-addr: 127.0.0.1:8848
    #gateway的配置
    gateway:
      #路由配置 [路由 就是指定当请求满足什么条件的时候转到哪个微服务]
      routes:
          #gateway唯一标识
        - id: gateway-route
          #需要转发的地址,lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
          uri: lb://order-service
          #断言规则,就是路由转发要满足的条件
          predicates:
              #当请求路径满足Path指定的规则时,才进行路由转发
            - Path=/order-ser/**
          #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
          filters:
              # 转发之前去掉第一层路由
            - StripPrefix=1

二、断言工厂

1.断言工厂介绍,上面项目使用了path,其它的可以参照path使用

官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

001

002

2.自定义断言工厂

003

创建类(可以仿照AbstractRoutePredicateFactory实现类编写)


package cn.luoruiyuan.predicates;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;

@Component
public class LryRoutePredicateFactory  extends AbstractRoutePredicateFactory<LryRoutePredicateFactory.Config> {

    public LryRoutePredicateFactory() {
        super(Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange exchange) {
                //参数为a成功
                if("a".equals(config.name)){
                    return true;
                }else{
                    return false;
                }
            }
        };
    }

    @Validated
    public static class Config {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

配置文件修改


访问参数获取



 三、过滤器工厂

1.常用类介绍

官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

  004
   005

2.自定义过滤工厂

创建类

package cn.luoruiyuan.filters;

import cn.luoruiyuan.predicates.LryRoutePredicateFactory;
import io.netty.util.internal.StringUtil;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.cloud.gateway.support.GatewayToStringStyler;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

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

@Component
public class LryGatewayFilterFactory  extends AbstractGatewayFilterFactory<LryGatewayFilterFactory.Config> {

    public LryGatewayFilterFactory() {
        super(LryGatewayFilterFactory.Config.class);
    }

    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //参数为b直接返回,其它的设置状态码为404
                if(("b").equals(config.name)){
                    return chain.filter(exchange);
                }else{
                    exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                    Mono<Void> voidMono = exchange.getResponse().setComplete();
                    return voidMono;
                }
            }
        };
    }


    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    public static class Config {
        protected String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

修改配置


访问获取参数


四、全局过滤器

1.默认实现的过滤器

006

2.创建过滤器


package cn.luoruiyuan.filters;

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

@Component
public class LryLogFilterFactory implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("日志输出:"+exchange.getRequest().getPath().value());
        return chain.filter(exchange);
    }
    
}

五、启动访问日志

007

六、跨域设置

1.配置文件方式


2.配置类方式

009


(1)