SpringCloud-Gateway的详细讲解以及完整的示意图和代码演示

news2024/10/6 16:18:51

目录

SpringCloud Gateway

看一个需求,引出网关服务

Gateway 网络拓扑图-背下来 

 Gateway 是什么

Gateway 核心功能

Gateway VS Zuul

Gateway 和Zuul 区别

Gateway 基本原理​编辑

 解读:

Route(路由)

Predicate(断言)

Filter(过滤)

 How It Works 工作机制

 梳理流程(how to work)

搭建Gateway 微服务 

 解读

代码实现

特别说明:

创建application.yml(重点核心) 内容如下:

创建主启动类GateWayApplication20000.java

测试

注意事项和细节

二说Gateway 路由配置

创建com/springcloud/config/GateWayRoutesConfig.java 

测试

动态路由

示意图 

代码实现

测试

注意事项和细节

代码

Predicate/断言

基本介绍

Route Predicate Factories

解读

Route Predicate 实例

After Route Predicate

测试

Before Route Predicate

Between Route Predicate

 Cookie Route Predicate

Header Route Predicate

Host Route Predicate

​编辑Method Route Predicate

Path Route Predicate

Query Route Predicate

 RemoteAddr Route Predicate

 Filter/过滤器

基本介绍

解读

类型

1 GatewayFilter

2 GlobalFilter 

GatewayFilter 使用

​编辑

2. 修改e-commerce-gateway-20000 的application.yml

3. 验证

自定义GlobalFilter

代码实现

测试


SpringCloud Gateway

看一个需求,引出网关服务

1、有一个前后端分离项目, 分析如图

 2、使用网关服务, 重构项目架构

Gateway 网络拓扑图-背下来 

 Gateway 是什么

1. Gateway 是在Spring 生态系统之上构建的API 网关服务,基于Spring ,Spring Boot 和Project
Reactor 等技术。

2. Gateway 旨在提供一种简单而有效的方式来对API 进行路由,以及提供一些强大的过滤器能,
例如∶熔断、限流、重试等. 

官网
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/ 

Gateway 核心功能

1 鉴权

2 流量控制

3 熔断

4 日志监控

5 反向代理

Gateway VS Zuul

Gateway 和Zuul 区别

1. SpringCloud Gateway 作为Spring Cloud 生态系统中的网关,目标是替代Zuul.

2. SpringCloud Gateway 是基于Spring WebFlux 框架实现的.

3. Spring WebFlux 框架底层则使用了高性能的Reactor 模式通信框架Netty , 提升了网关性能.

Gateway 特性

Spring Cloud Gateway 基于Spring Framework(支持Spring WebFlux),Project Reactor 和Spring Boot 进行构建,具有如下特性:

 1.动态路由.

 2.可以对路由指定Predicate(断言)和Filter(过滤器) 

 3. 集成Hystrix的断路器功能

 4.集成Spring Cloud 服务发现功能

 5.请求限流功能

 6.支持路径重写

Gateway 基本原理

 解读:

1. web 请求,通过一些匹配条件,定位到真正的服务节点/微服务模块,在这个转发过程的前后,进行一些精细化控制。

2. predicate: 就是匹配条件.

3. filter: 可以理解为是网关的过滤机制。有了predicate 和filter,再加上目标URL.就可以实现一个具体的路由.

Route(路由)

一句话: 路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true 则匹配该路由.

Predicate(断言)

1、一句话: 对HTTP 请求中的所有内容(例如请求头或请求参数)进行匹配,如果请求与断言相匹配则进行路由.

2、简单举例, 比如配置路径, - Path=/member/get/** #断言,路径相匹配的进行路由转发, 如果Http 请求的路径不匹配, 则不进行路由转发.

Filter(过滤)

1、一句话: 使用过滤器,可以在请求被路由前或者之后对请求进行处理

2、你可以理解成, 在对Http 请求断言匹配成功后, 可以通过网关的过滤机制, 对Http 请求处理

简单举例:
filters:
- AddRequestParameter=color, blue #过滤器在匹配的请求头加上一对请求头,名称
为color 值为blue
, 比如原来的http 请求是http://localhost:10000/member/get/1 ==过滤器处理=>
http://localhost:10000/member/get/1?color=blue

 How It Works 工作机制

 梳理流程(how to work)

1. 客户端向Spring Cloud Gateway 发出请求。然后在Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到Gateway Web Handler。

2. Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。

3. 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前("pre")或之后("post")执行业务逻辑。

4. Filter 在"pre"类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,

5. 在"post"类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。..........................

一句话说:路由转发+执行过滤器链

搭建Gateway 微服务 

引入Gateway 项目架构

 解读

1. 通过网关暴露的接口,实现调用真正的服务
2. 网关本身也是一个微服务模块

 

代码实现

1. 参考member-service-consumer-80 创建e-commerce-gateway-20000(具体步骤参考以前)

2. 修改pom.xml, 部分内容可以从member-service-consumer-80 的pom.xml 拷贝

   <artifactId>e-commerce-gateway-20000</artifactId>


    <!--引入相关的依赖: 我们引入了当前需要的依赖,后面如果有其它需要,再灵活调整-->
    <dependencies>

        <!--引入gateway-starter  网关场景启动器starter: 使用版本仲裁-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!--引入eureka client 场景启动器starter-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--特别说明:
        1.  不要引入spring-boot-starter-web 和 spring-boot-starter-actuator
            否则会出现冲突
        2.  因为gateway 是一个服务网关,不需要web...
        -->


        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--引入e_commerce_center-common-api-->
        <dependency>
            <groupId>com.wyxedu.springcloud</groupId>
            <artifactId>e_commerce_center-common-api</artifactId>
            <version>${project.version}</version>
        </dependency>

    </dependencies>

特别说明:

1.  不要引入spring-boot-starter-web 和 spring-boot-starter-actuator否则会出现冲突

2.  因为gateway 是一个服务网关,不需要web..

创建application.yml(重点核心) 内容如下:

server:
  port: 20000

spring:
  application:
    name: e-commerce-gateway
  cloud:
    gateway:
      routes: #配置路由,可以配置多个路由 List<RouteDefinition> routes
        - id: member_route01 #路由的id, 程序员自己配置,要求唯一
          #gateway 最终访问的url 是 url=uri+Path
          #匹配后提供服务的路由地址: 也可以是外网 http://www.baidu.com
          #比如: 客户端/浏览器请求 url http://localhost:20000/member/get/1
          #如果根据Path匹配成功 最终访问的url/转发url 就是 url=http://localhost:10000/member/get/1
          #如果匹配失败, 则有gateway返回404信息
          #疑问: 这里配置的 uri 是固定,在当前这种情况其实可以没有有Eureka Server,后面会使用灵活方式
          #     配置,就会使用到Eureka Server
          uri: http://localhost:10000
          predicates: #断言,可以有多种形式
            - Path=/member/get/**
        - id: member_route02 #路由的id, 程序员自己配置,要求唯一
          uri: http://localhost:10000
          predicates: #断言,可以有多种形式
            #这时如果客户端/浏览器 访问gateway 的url http://localhost:20000/member/save
            #匹配Path成功 最终访问的url 就是 http://localhost:10000/member/save
            - Path=/member/save
           
#配置Eureak-Client

eureka:
  instance:
    hostname: e-commerce-service #先配置着
  client:
    register-with-eureka: true #将自己注册到Eureka-Server
    fetch-registry: true
    service-url:
      #表示将自己注册到哪个eureka-server
      #这里为了方便,使用Eureka Server的单机环境测试
      defaultZone: http://eureka9001.com:9001/eureka

创建主启动类GateWayApplication20000.java

@SpringBootApplication
@EnableEurekaClient
public class GateWayApplication20000 {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication20000.class,args);
    }
}

测试

1 启动e-commerce-eureka-server-9001

2 启动member-service-provider-10000

3 启动e-commerce-gateway-20000

4 浏览器:(通过网关访问) http://localhost:20000/member/get/1

Postman 测试添加(走网关)
请求地址: http://localhost:20000/member/save 

json 数据:
{
"name": "天山童姥",
"pwd": "hello",
"mobile": "110",
"email": "zz@sohu.com",
"gender": 2
}

 

注意事项和细节

1. 因为我们的端口号10000的member 的controller 的方法参数使用了@RequestBody 

    @PostMapping(value = "/member/save")
    public Result save(@RequestBody Member member) {//增加
        log.info("会员服务方接收到member= " + member);
        int result = memberService.save(member);
        log.info("reset= " + result);
        if (result > 0) { //成功
            return Result.success("添加用户成功member-service-provider-10000", result);
        } else {
            return Result.error("401", "添加用户失败");
        }
    }

2. 所以,在使用postman 时,需要使用json 格式发送数据, 否则会报400 错误

3. 回顾:@RequestBody 的作用是: 将前端发送的json 数据封装成对象, 如果发送的不是json 数
据,会报错误

二说Gateway 路由配置

1 方式1: application.yml 中配置-前面讲过
2 方式2: 编写配置类注入【了解】

先注销application.yml 对网关路由部分注销 网关部分只保留

spring:
  application:
    name: e-commerce-gateway

2. 重启e-commerce-gateway-20000, 再次测试,网关路由失效

3. 参考官方文档

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#spring-cloud-circuitbreaker-filter-factory ,

创建com/springcloud/config/GateWayRoutesConfig.java 

@Configuration
public class GateWayRoutesConfig {

   //配置注入路由

   /**
    * 在理解通过配置类注入/配置 路由,可以对照前面的application.yml来对比理解
    * cloud:
    *     gateway:
    *       routes: #配置路由,可以配置多个路由 List<RouteDefinition> routes
    *         - id: member_route01 #路由的id, 程序员自己配置,要求唯一
    *           #gateway 最终访问的url 是 url=uri+Path
    *           #匹配后提供服务的路由地址: 也可以是外网 http://www.baidu.com
    *           #比如: 客户端/浏览器请求 url http://localhost:20000/member/get/1
    *           #如果根据Path匹配成功 最终访问的url/转发url 就是 url=http://localhost:10000/member/get/1
    *           #如果匹配失败, 则有gateway返回404信息
    *           #疑问: 这里配置的 uri 是固定,在当前这种情况其实可以没有有Eureka Server,后面会使用灵活方式
    *           #     配置,就会使用到Eureka Server
    *           uri: http://localhost:10000
    *           predicates: #断言,可以有多种形式
    *             - Path=/member/get/**
    */
   @Bean
   public RouteLocator myRouteLocator04(RouteLocatorBuilder routeLocatorBuilder) {

       RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

       //方法写完
       //梳理
       //1. 下面的方法我们分别指定了id , uri 和path
       //2. Function<PredicateSpec, Route.AsyncBuilder> fn
       //(1) 是一个函数式接口
       //(2) 接收的类型是 PredicateSpec ,返回的类型是 Route.AsyncBuilder
       //(3) r -> r.path("/member/get/**")
       //                .uri("http://localhost:10000") 就是lambda表达式
       //(4) 一会还要用代码进行说明-先使用-再理解
       //3. 小伙伴们可以理解这是一个规定写法

       return routes.route("member_route04", r -> r.path("/member/get/**")
               .uri("http://localhost:10000"))
               .build();


   }

   @Bean
   public RouteLocator myRouteLocator05(RouteLocatorBuilder routeLocatorBuilder) {

       RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

       return routes.route("member_route05", r -> r.path("/member/save")
               .uri("http://localhost:10000"))
               .build();

   }
}

测试

1 启动e-commerce-eureka-server-9001

2 启动member-service-provider-10000

3 启动e-commerce-gateway-20000

4 浏览器:(通过网关访问) http://localhost:20000/member/get/1

结果和前面的一样这里就不再展示了

方别忘了,将代码恢复成yml 配置

 

动态路由

示意图 

代码实现

1. 修改e-commerce-gateway-20000 的application.yml

spring:
  application:
    name: e-commerce-gateway
  cloud:
    gateway:
      routes: #配置路由,可以配置多个路由 List<RouteDefinition> routes
        - id: member_route01 #路由的id, 程序员自己配置,要求唯一
          #gateway 最终访问的url 是 url=uri+Path
          #匹配后提供服务的路由地址: 也可以是外网 http://www.baidu.com
          #比如: 客户端/浏览器请求 url http://localhost:20000/member/get/1
          #如果根据Path匹配成功 最终访问的url/转发url 就是 url=http://localhost:10000/member/get/1
          #如果匹配失败, 则有gateway返回404信息
          #     配置,就会使用到Eureka Server
          #解读
          #1. lb: 协议名 , member-service-provider 注册到eureka server 服务名(小写)
          #2. 默认情况下,负载均衡算法是轮询
          uri: lb://member-service-provider
          predicates: #断言,可以有多种形式
            - Path=/member/get/**

        - id: member_route02 #路由的id, 程序员自己配置,要求唯一
          uri: lb://member-service-provider
          predicates: #断言,可以有多种形式
            #这时如果客户端/浏览器 访问gateway 的url http://localhost:20000/member/save
            #匹配Path成功 最终访问的url 就是 http://localhost:10000/member/save
            - Path=/member/save

测试

1 启动e-commerce-eureka-server-9001

2 启动member-service-provider-10000

3 启动e-commerce-gateway-20000

4 浏览器:(通过网关访问) http://localhost:20000/member/get/1

 

Postman 测试添加(走网关, 前面演示过了这里就不再展示了) 

注意事项和细节

1 配置好动态路由后Gateway 会根据注册中心上微服务名,为请求创建动态路由,实现动态路由功能

2 使用的lb 协议支持负载均衡-轮询算法

3 配置自己的负载均衡算法, 测试完毕恢复成原来的轮询算法

代码

/**
* RibbonRule: 配置类-配置自己的负载均衡算法
*/
@Configuration
public class RibbonRule {

   //配置注入自己的负载均衡算法
   @Bean
   public IRule myRibbonRule() {
       //这里老师返回的是RandomRule,当然小伙伴也可以自己指定
       return new RandomRule();
   }
}

Predicate/断言

基本介绍

一句话: Predicate 就是一组匹配规则,当请求匹配成功,就执行对应的Route, 匹配失败,放弃处理/转发

Route Predicate Factories

- 文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读

1. Spring Cloud Gateway包括许多内置的Route Predicate工厂, 所有这些Predicate都与HTTP请求的不同属性匹配, 可以组合使用.

2. Spring Cloud Gateway 创建Route 对象时,使用RoutePredicateFactory 创建Predicate对象,Predicate 对象可以赋值给Route。

3. 所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合

Route Predicate 实例

After Route Predicate

需求: 只有2022-11-18 12:35:50 之后的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

注意这里只展示需要修改的地方了全部配置上面有 

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]

 3. 如何获取时间格式, 创建一个测试类,来获取当前时间,再根据需要修改

springcloud/T2.java

public class T2 {
    public static void main(String[] args) {
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);
    }
}

测试

 

启动e-commerce-eureka-server-9001
启动member-service-provider-10000/10002
启动e-commerce-gateway-20000
浏览器:(通过网关访问) http://localhost:20000/member/get/1

Before Route Predicate

需求: 只有2022-11-18 12:35:50 之前的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

 2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]

测试步骤和前面的一样这个就不再冲重复了

Between Route Predicate

需求: 只有2020-11-18 12:35:50 和2022-11-18 12:35:50 之间的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
-
Between=2020-11-18T12:35:50.387+08:00[Asia/Shanghai],2022-11-18T12:35:50.387+0
8:00[Asia/Shanghai]

 Cookie Route Predicate

需求: 请求带有cookie 键: user 值: nihao才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

解读:
chocolate 是cookie 名字ch.p 是cookie 的值,是按照正则表达式来匹配的 

2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#-Between=2020-11-18T12:35:50.387+08:00[Asia/Shanghai],2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
- Cookie=user, nihao

这个有点特殊所以单独截图

 如果和前面的一样这里就不在展示了

Header Route Predicate

需求: 请求头Header 有X-Request-Id, 并且值hello 才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

解读: X-Request-Id 是header 的名称, \d+ 是一个正则表达式 

2. 修改e-commerce-gateway-20000 的application.yml

#- Cookie=key1, abc
- Header=X-Request-Id, hello

Host Route Predicate

需求: 请求Host 是**.wyxedu.** 才匹配/断言成功, 比如Host www.wyxedu.com 

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: Host 可以有多个, 使用逗号间隔 

2. 修改e-commerce-gateway-20000 的application.yml

#- Header=X-Request-Id, hello
- Host=**.wyxedu.**

Method Route Predicate

 需求: 请求是Get 方式才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: 请求方式可以有多个, 使用逗号间隔 

2. 修改e-commerce-gateway-20000 的application.yml

#- Host=**.wyxedu.**
- Method=GET

 注意 我们设置的GET方式 所以会报错

Path Route Predicate

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: Path 可以有多个, 使用逗号间隔 

Query Route Predicate

需求: 请求有参数email ,并且满足电子邮件的基本格式, 才能匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

 解读: red 是参数名gree. 是值, 支持正则表达式

2. 修改e-commerce-gateway-20000 的application.yml

#- Host=**.wyxedu.**
#- Method=GET
- Query=email, [\w-]+@([a-zA-Z]+\.)+[a-zA-Z]+

注意启动哪些服务都是一样的

这里再提醒一下

启动e-commerce-eureka-server-9001
启动member-service-provider-10000/10002
启动e-commerce-gateway-20000 

 RemoteAddr Route Predicate

需求: 请求的IP 是127.0.0.1, 才能匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

#提示:通过http://127.0.0.1:20000/member/get/1 ,可以看到效果.
- RemoteAddr=127.0.0.1

 

注意因为本机默认ip是127.0.0.1 所以可以不用直接指定 但是如果是其他的ip就需要指定

如请求的是192.168.1.2 如果想要看到效果的话就 http://192.168.1.2:20000/member/get/1

测试完毕,记得代码恢复到测试前 

 

 Filter/过滤器

基本介绍

1. 文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

解读

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应
Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生 

类型

1 GatewayFilter

2 GlobalFilter 

文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#global-filters

 

GatewayFilter 使用

1 开发直接使用GatewayFilter 较少,一般是自定义过滤器
2 参考实例

 参考文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-addrequestheader-gatewayfilter-factory 

 

2. 修改e-commerce-gateway-20000 的application.yml

            #- RemoteAddr=127.0.0.1
          filters:
            - AddRequestParameter=color, blue#过滤器工厂会在匹配的请求头加上一对请求头,名称为color 值为blue
            - AddRequestParameter=age, 18#过滤器工厂会在匹配的请求头加上一对请求头,名称为age 值为18

3. 验证

修改member-service-provider-10000\src\main\java\com\springcloud\controller\MemberController.java

@GetMapping("/member/get/{id}")
    public Result getMemberById(@PathVariable("id") Long id, HttpServletRequest request) {

        String color = request.getParameter("color");
        String address = request.getParameter("age");

        Member member = memberService.queryMemberById(id);

        //使用Result把查询到的结果返回
        if (member != null) {
            return Result.success("查询会员成功 member-service-provider-10000 " + color + "-" + age, member);
          
        } else {
            return Result.error("402", "ID= " + id + "不存在");
        }

    }

自定义GlobalFilter

1 需求分析/图解
1. 自定义全局GlobalFilter 过滤器
2. 如果请求参数user=wyxdu, pwd=123456 则放行, 否则不能通过验证 

代码实现

1. 在e-commerce-gateway-20000 创建com/springcloud/filter/CustomGateWayFilter.java

@Component
public class CustomGateWayFilter implements GlobalFilter, Ordered {

   //filter是核心的方法,将我们的过滤的业务,写在该方法中
   @Override
   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       System.out.println("------CustomGateWayFilter------");
       //先获取到对应的参数值
       //比如 http://localhost:20000/member/get/1?user=wyxedu&pwd=123456
       String user =
               exchange.getRequest().getQueryParams().getFirst("user");
       String pwd = exchange.getRequest().getQueryParams().getFirst("pwd");
       if(!("wyxdu".equals(user) && "123456".equals(pwd))) {//如果不满足条件
           System.out.println("-----非法用户-----");
           exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//回应
           return exchange.getResponse().setComplete();
       }
       //验证通过, 放行
       return chain.filter(exchange);
   }


   //order 表示过滤器执行的顺序, 数字越小, 优先级越高
   @Override
   public int getOrder() {
       return 0;
   }
}

测试

1 启动e-commerce-eureka-server-9001
2 启动member-service-provider-10000/10002
3 启动e-commerce-gateway-20000
4 浏览器:(通过网关访问) http://localhost:20000/member/get/1?user=wyxdu&pwd=123456

如果不通过就 显示这个

 

 测试完毕,记得代码恢复到测试前

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/559782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络——shell编程之firewalld防火墙

Linux网络——shell编程之firewalld防火墙 一、firewalld概述二、iptables与firewalld的联系与区别1.iptables与firewalld的区别2.iptables与firewalld的联系 三、firewalld区域1.firewalld的九个区域2.firewalld区域介绍3.firewalld数据处理流程4.firewalld检查数据包源地址的…

【shell编程学习】反弹shell

反弹实验 机器IPwin10虚拟机192.168.242.129攻击机centos 虚拟机192.168.242.131靶机 1&#xff0c;win10机器安装Ncat 来监听端口 简单来说&#xff0c;就是下载netcat 安装包&#xff0c;解压&#xff0c;将nc.exe 复制到C:\Windows\System32的文件夹下。即可使用nc命令来…

悦亮少儿眼科樊广祥:远视储备是妈妈都该知道的眼科知识!

近视的“低龄化”和“高度化”问题日益严重&#xff0c;如何预防近视或推迟近视发生&#xff0c;已成为大家都非常关注的话题。这其中&#xff0c;“远视储备”一词也为越来越多的人所知晓。 为了帮助大家更好的理解远视储备、从而帮助孩子预防近视&#xff0c;悦亮少儿眼科(宁…

Java 期末复习进阶版

(一) 方法重载 1.同一个类中多个方法具有相同的方法名,不同的______称为方法的重载.(参数列表) 2.在某个类中存在一个方法:void getSort(int x),以下能作为这个方法的重载的声明的是(C). A)public getSort(float x) B)int getSort(int y) C)double getSort(int x,int y) D)vo…

Docker安装Yearning3.1.4/禅道18.4【亲测可用】

一、安装Yearning 1、建议先安装go 2、在mysql下新建yearning数据库&#xff1a; 进入mysql&#xff1a;docker exec -it 91ada9def680 /bin/bash 账号密码登录&#xff1a;mysql -uroot -p create database if not exists yearning default character set utf8mb4 collat…

MOSN 基于延迟负载均衡算法——走得更快,期待走得更稳

文&#xff5c;纪卓志&#xff08;GitHub ID&#xff1a;jizhuozhi) 京东高级开发工程师 MOSN 项目 Committer 专注于云原生网关研发的相关工作&#xff0c;长期投入在负载均衡和流量控制领域 前言 这篇文章主要是介绍 MOSN 在 v1.5.0 中新引入的基于延迟的负载均衡算法#2…

指针---C语言

目录 前言&#xff1a; 一.指针基础 1.1内存单元 1.2内存单元和指针的大小 二.指针变量 2.1指针类型 2.2野指针 三.指针运算 四.指针和数组的关系 4.1下标与解引用的等价替换 4.2指针数组 五.二级指针 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的…

如何获取HTTP请求时间与响应时间【附源码】

文章目录 一、问题描述二、抓包观察三、查找文档四、思考尝试五、精益求精六、源码解说 一、问题描述 今日遇到了一个问题&#xff0c;要去获取HTTP报文在请求和响应的时间&#xff0c;因为没有原生的API可以调用&#xff0c;所以需要一定的技巧~ 下面主体的框架和代码&#xf…

如何在 Linux 服务器上更改分区方案?

在 Linux 服务器上&#xff0c;分区方案对于数据存储和系统管理至关重要。当服务器的存储需求发生变化或者需要重新组织分区时&#xff0c;更改分区方案是一个常见的任务。 本文将详细介绍如何在 Linux 服务器上更改分区方案。 步骤一&#xff1a;备份数据 在更改分区方案之前…

Microsoft Office 2013安装

哈喽&#xff0c;大家好。今天一起学习的是office2013的安装&#xff0c;有兴趣的小伙伴也可以来一起试试手。 一、测试演示参数 演示操作系统&#xff1a;Windows 7 支持Win10安装&#xff0c;不建议Win11安装&#xff0c;不支持WinXP系统 系统类型&#xff1a;64位 演示版本…

Jmeter函数助手函数--计数器详解

函数 作用 ${__counter(,)} 计数器&#xff0c;每次加1 ${__dateTimeConvert(,,,)} 时间格式转换 ${__intSum(,,)} 整数相加 ${__P(,)} 获取属性 ${__setProperty(,,)} 设置属性 ${__Random(,,)} 随机数 ${__threadNum} 线程编号 ${__time(,)} 获取当前时间戳…

Axure教程-竖向堆叠图(中继器)

本文将教大家如何用AXURE中的中继器动态竖向堆叠图 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://wo8zqr.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87810606 二、功能介绍 简单填写中继器内容即可生成动态竖向堆…

Day5 模块(单元)测试——单元测试、自顶向上测试、自下向上测试

Day5 模块(单元)测试——单元测试、自顶向上测试、自下向上测试 文章目录 Day5 模块(单元)测试——单元测试、自顶向上测试、自下向上测试什么是单元测试?单元测试结构化程序时代单元测试与使用单元测试的误解单元测试过程成本效率不高结论单元测试的优点测试用例白盒覆盖…

SAP 用CO13冲销工序报工,但是没有产生货物移动(TCODE:CO1P 、 SE38 :CORUPROC,CORUAFWP)

前言 通常情况下&#xff0c;对PPO做GI或GR的时候&#xff0c;出现的异常可以在COGI中间被列出&#xff1b;在这些数据进入COGI之前&#xff0c;系统会把这些数据记录在CO1P中&#xff1b;换句话说&#xff0c;系统有时会出现DB的更新延时&#xff0c;当延时发生的时候&#xf…

从零实现一个数据库(DataBase) Go语言实现版 6.持久化到磁盘

英文源地址 持久化至磁盘 前一章中的b树数据结构可以很容易地转存到磁盘上.让我们在它之上建立一个简单地kv存储. 由于我们的b树实现是不可变的, 我们将以仅追加的方式分配磁盘空间, 重用磁盘空间将推迟到下一章. 持久化数据的方式 正如前面章节所提到的, 将数据持久化到磁…

黑马程序员的基础班都是一些什么内容?

黑马推出了基础班的课程&#xff0c;各学科点击申请基础班试学 Java学科基础班 JavaSE基础基础班阶段一 课时:9天 技术点:60项 测验:1次 学习方式:线下面授 学习目标 1.掌握Java开发环境基本配置 2.掌握运算符、表达式、流程控制语句、数组等的使用 3.熟练使用IDEA开发工具…

SQL优化的思路和步骤

数据库优化 创建索引: 创建合适的索引提高查询速度 分库分表:当一张表的数据比较多或者一张表的某些字段的值比较多并且使用时改用水平分表和垂直分表来优化 读写分离(集群): 当一台服务不能满足需要时&#xff0c;采用读写分离的方式进行集群 缓存: 使用redis来进行缓存 …

ServerBoss:国产免费的Linux连接工具,服务器管理工具

在这个数字化时代&#xff0c;Linux正在成为越来越多企业的首选操作系统。但是&#xff0c;由于它复杂的命令行界面和复杂的文件系统&#xff0c;许多用户可能会认为Linux不太友好和难以驾驭。同时目前大部分Linux连接工具都是国外产品&#xff0c;且需要商业授权。在此背景下&…

案例14:Java酒店管理系统设计与实现开题报告

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

产研团队任务管理工具:盘点国内外9款知名任务管理系统软件

以下是10款国内外最知名的任务管理系统&#xff1a;1.研发项目任务管理-PingCode&#xff1b;2.通用项目任务管理-Worktile&#xff1b;3.免费开源研发任务工具-Redmine&#xff1b;4.海外著名项目任务管理工具-Asana&#xff1b;5.免费任务管理软件-Trello&#xff1b;6.个人任…