SpringCloud Gateway用法详解

这篇具有很好参考价值的文章主要介绍了SpringCloud Gateway用法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

零、人在月球

目录

零、人在月球

一、功能简介

1、网关是一个服务:

二、Gateway 断言

1、path断言

2、Query断言

3、Method断言

4、Host断言

5、Cookie断言

6、Header断言

7、Weight 权重路由

8、After 时间路由

9、Before 时间路由

10、Between时间区间路由

11、灰度发布

三、Gateway 过滤器

1、增加header 请求头

2、新增动态header请求头

3、设置请求头 过滤器配置,修改移除请求头

4、PreserverHostHeader

5、重写response加密密码

6、response去重

7、路径带前缀 请求/get/app 其实是/prefix/get

8、配置30几 跳转到指定地址

9、修改状态码

10、转发地址

11、去掉增加 请求路径中部分层级

12、重试过滤器

13、过滤器设置请求大小

14、spring-session

15、默认filter

四、熔断机制?

1、老熔断

2、熔断机制-新的

五、限流配置

1、增加依赖

2、配置redis:spring.redis.database:XX

3、配置keyResolver,参考类RateLimiteConfig

4、ym配置spring.cloud.gateway.routes

5、当发生限流,会向redis存储两个数据 .限流返回状态码是429

6、配置文件RateLimiteConfig.java

六、自定义谓词配置类

1、配置类UserNameCheckRoutePredicateFactory.java

2、配置项

七、自定义过滤器

1、配置类

pre配置类

post过滤器

3、配置文件

八、全局过滤器

九、网关超时配置

十、元数据 metadata

十一、gateway内置API与跨域

1、API说明:

2、打开端点配置

3、跨域请求:


一、功能简介

1、网关是一个服务:
Spring Cloud GateWay是Spring Cloud的个全新项,标是取代Netflix Zuul,基于Spring5.0+SpringBoot2.0+WebFlux(基于性能的Reactor模式响应式通信框架Netty,异步阻塞模型)等技术开发,性能于Zuul,官测试,GateWay是Zuul的1.6倍,旨在为微服务架构提供种简单有效的统的API路由管理式
网关:
一、流量网关
1、全局性流控 匹配路由 gateway转发前端地址、后端地址、文件服务器、调度器、消息中心 OK!
2、日志统计 可以统计到所有到前端后端接口 OK
3、防止SQL注入 – 未使用
4、防止web攻击 --未使用
5、屏蔽工具扫描 --未使用
6、黑白IP名单 通过filter过滤IP禁止访问
7、证书/加解密处理 --未使用

二、业务网关
1、服务级别流控 前端访问后端通过网关 OK!
2、服务降级和熔断 统一后端接口熔断降级、POST接口限流1s/1次 OK!
3、路由与负载均衡、灰度的策略 负载均衡OK! 灰度需要部署集群
4、服务过滤、聚合与发现 通过注册中心,自定义谓词与自定义过滤器 OK!
5、权限验证与用户等级策略 – 使用app端的权限
6、业务规则与参数校验 --未使用
7、多级缓存策略 --未使用

二、Gateway 断言

依赖:org.springframework.cloud:spring-cloud-starter-gateway

父依赖:

dependencyManagement {
imports {
mavenBom “org.springframework.cloud:spring-cloud-dependencies: s p r i n g C l o u d V e r s i o n " m a v e n B o m " c o m . a l i b a b a . c l o u d : s p r i n g − c l o u d − a l i b a b a − d e p e n d e n c i e s : {springCloudVersion}" mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies: springCloudVersion"mavenBom"com.alibaba.cloud:springcloudalibabadependencies:{comAlibabaCloud}”
}
}

断言:predicates 多断言可以配合使用

1、path断言

predicates:

-Path=/mg

2、Query断言

参数值可以写正则,也可以只写参数名

predicates:

-Query=foo,ba.

3、Method断言

predicates:

-Method=get

4、Host断言

predicates:

-Host=mashibing.com

5、Cookie断言

predicates:

-Cookie=name,yiming

6、Header断言

predicates:

-Header=reqId,9090d+ #正则表达式d+ 数字

7、Weight 权重路由

- id: weight2
  uri: http://localhost:6601
  predicates:
    - Path=/api/**
    - Weight=group1,2
  filters:
    - StripPrefix=1
- id: weight8
  uri: http://localhost:6602
  predicates:
    - Path=/api/**
    - Weight=group1,8
  filters:
    - StripPrefix=1

8、After 时间路由

#After
      - id: after_route
        uri: lb://micore-test1
        predicates:
          - After=2022-02-07T17:05:00.789+08:00[Asia/Shanghai]

9、Before 时间路由

- Before=2022-02-07T17:05:00.789+08:00[Asia/Shanghai]

10、Between时间区间路由

- Between=2021-02-07T17:05:00.789+08:00[Asia/Shanghai],2022-02-07T17:05:00.789+08:00[Asia/Shanghai]

11、灰度发布

同一个请求地址,设置多个url也就是多个服务。比如M5,和MD5 两个服务,比重设置95%和5%。先升级一部分的服务,再切换另一个服务进行升级。

三、Gateway 过滤器

1、增加header 请求头

附加:代码中获取请求头 JSONView插件

spring.cloud.gateway.routes
-id: add_request_header
uri: lb://test-prod
predicates: 
    -Path= /getheader
filters:
    #增加请求头、请求参数
    -AddRequestHeader= X-Request-id, 99999
    -AddRequestHeader= X-Request-author, kevin
    -AddRequestParameter= param-id,99999
    -AddRequestParameter= param-author, kevin
    -AddResponseHeader=rep-id, 99999
    -AddResponseHeader=req-author,kevin

java代码获取header 和请求参数param 和response

@GetMapping("getHeaders")
public Map<String,String> getHeaders(HttpServletRequest request){
    Map<String,String> map =new HashMap<>();
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String name = headerNames.nextElement();
        String value = request.getHeader(name);
        map.put(name,value);
    }
    return map;
}

@GetMapping("getParameter")
public Map<String,String[]> getparam(HttpServletRequest request){
    Map<String,String[]> paramMap=request.getParameterMap();
    return paramMap;
}

@GetMapping("getResponseHeader")
public Map<String,Collection<String>> getheader3(HttpServletResponse response){
    response.addHeader("req-id","123456");
    response.addHeader("req-id","1234567");
    response.addHeader("rep-url","/42?user=ford&paddwd=omg!what&flag=true");
    Map<String,Collection<String>>map=new HashMap<>();
    Collection<String> headerNames=response.getHeaderNames();
    for(String name:headerNames){
        Collection<String> headers=response.getHeaders(name);
        map.put(name,headers);
    }
    return map;
}

2、新增动态header请求头

predicates:
    -Path= /getheader/{seq}
filters:
    -AddRequestHeader= X-Request-id, 99999-{seq}
    -AddRequestHeader= X-Request-author, kevin-{seq}
    -AddRequestParameter= param-id,99999-{seq}
    -AddRequestParameter= param-author, kevin-{seq}
    -AddResponseHeader=rep-id, 99999-{seq}
    -AddResponseHeader=req-author,kevin-{seq}

方法:@GetMapping(“getHeader/{param}”)

3、设置请求头 过滤器配置,修改移除请求头

#设置请求头,没有则新增,有则修改
-SetRequestHeader=X-Request-id,9999
#移除请求头、请求参数
-RemoveRequestHeader= X-Request-id
-RemoveRequestParameter=X-Request
-RemoveRequestParameter=X-Request-author
#先从header取from-Header,如果有则赋值给to-Header,如果没from-Header则无效果
-MapRequestHeader=from-Header,to-Header

4、PreserverHostHeader

#默认开启,在gateway转发请求前把原始请求的host头部带上,转发给目的服务

-PreserverHostHeader

5、重写response加密密码

#例如: req-url=/42user=ford&passwd=omg!what&flag=true 经过下面配置替换为/42user=ford&passwd=***&flag=true

-RewriteResponseHeader=req-url,passwd=[^&]+,passwd=***

6、response去重

RETAIN_FIRST保留第一个

RETAIN_LAST保留最后一个

RETAIN_FIRST RETAIN_UNIQUE 保留唯一

-DedupeResponseHeader= req-id,RETAIN_FIRST

7、路径带前缀 请求/get/app 其实是/prefix/get

-PrefixPath= /prefix

8、配置30几 跳转到指定地址

#300 Multiple多种选择,请求的资源可能包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端选择

#301 Moved Permanently永久移动,请求的资源已被永久移动新位置,返回信息会包含URI,浏览器会自动定向到新地址,以后请求应该用新的URI代替

#302 Found 临时移动,与301类似,资源临时被移动,客户端应该继续使用原URI

#303See Other查看其它地址,与301类似。使用GET和POST请求查看

#304未修改,所请求资源未修改,服务器返回此状态吗时,不会返回任何资源

#305Use proxy 使用代理,所请求资源必须通过代理

#306 Unused 已经废弃的HTTP状态码

#307 Temporary Redirect 临时重定向,与302类似,使用GET请求重定向

? -RedirectTo=302,http://www.baidu.com 

-RedirectTo=301,http://www.taobao.com
?

9、修改状态码

#修改状态码,可以org.springframework.http.HttpStatus枚举,也可以直接写状态码

-SetStatus=NOT_FOUND
-SetStatus=404

10、转发地址

#访问/api/getheader 实际访问:/getheader,转发的目的地址必须写 / 否则会出错

-RewritePath=/api/getheader, /getheader

#http://192.168.31.80:8801/www/get/user/12123 实际访问:/prefix/get/user/12123

#http://192.168.31.80:8801/www/getheader 实际访问:/prefix/getheader

-RewritePath=/www/(?/?.*), /prefix/${segment}

转发例子2 例如请求/profix/get/user/12123 实际请求是 /get/user

predicates:
    -Path=/prefix/{var1}/{var2}/{var3}
filter:
    -SetPath=/{var1}/{var2}

11、去掉增加 请求路径中部分层级

#请求/api/get/123 实际请求/get/123

-StripPrefix=1 从前往后去掉一些路径

#请求/get/123 实际请求/prefix/get/123

-PrefixPath=/prefix 增加前缀路径

12、重试过滤器

predicates:
    -Path=/testRetry
filters:
    - name:  Retry  #过滤器名称
      args:
        retries: 3 #重试次数
        series: #org.springframework.http.HttpStatus.Series 枚举 什么类型状态码进行重试
            -SERVER_ERROR
            -CLIENT_ERROR
        statuses:#org.springframework.http.HttpStatus枚举值,什么状态码重试
            -BAD_GATEWAY
            -METHOD_NOT_ALLOWED
        methods: #什么类型方法重试
            -GET
            -POST
        exception: #什么异常进行重试
            -java.io.IOException
        backoff:#重试时间间隔
            firstBackoff: 10ms
            maxBackoff: 50ms
            factor: 2
            basedOnPreviousValue: false

13、过滤器设置请求大小

filters:
    -name: RequestSize #过滤器名称
     args:   #控制请求的大小,超过则返回413.请求最大默认5000000 约5M
        maxSize:1000  #1KB

14、spring-session

filters:
#只有当集成Spring Session才会将session放到Redis,来实现共享Session功能,如果项目继承了Spring Session中的Spring Security框架。如果希望安全验证信息可以转发到远程应用,那么这个配置是必须的
    - SaveSession

15、默认filter

spring.cloud.gateway.default-filters:
    -AddRequestHeader=X-Request-Default, Gateway

四、熔断机制

1、老熔断

①增加依赖包:org.springframework.cloud:spring-cloud-starter-netflix-hystrix

②默认熔断配置

spring.cloud.gateway
default-filters:
    -name: Hystrix #设置默认熔断器
     args:
        name: fallback1 #熔断器名字,随便起
        fallbackUrl: forward:/fallbackHysrix  //发生熔断后跳转的地址
#设置hystrix断路器超时时间
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMillliseconds:2000  #2秒

该地址:需要在gateway项目中新增一个controller com.longze.controller.FallbackController

@RestController
public class FallbackController {
    @RequestMapping("/fallbackHysrix")
    public String fallbackHysrix(){
        return "fallbackHystrix error";
    }
    @RequestMapping("/fallbackCircuitBreaker")
    public String fallbackCircuitBreaker(){
        return "fallbackCircuitBreaker error";
    }
}

③单独配置熔断器

spring.cloud.gateway.routes
filters:
    -name: Hystrix #设置熔断器
     args:
        name: fallbackcmd #熔断器名字,无所谓
        fallbackUri: forward:/fallbackHysrix #熔断之后跳转,本项目或其他项目配置
#熔断项目在其他项目中
-id: Hystrix-fallback
uri: http://localhost:9100
predicates:
    -Path: /fallbackHysrix

2、熔断机制-新的

①增加依赖包:org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j

和 org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j

②#开启resilience4j熔断

spring.cloud.circuitbreaker.resilience4j.enabled: true

③配置熔断 和Hystrix很相似

spring.cloud.gateway.routes

filters:
    -name: CircuitBreaker #设置熔断器
     args:
        name: testCircuitBreaker #熔断器名字,无所谓
        fallbackUri: forward:/fallbackCircuitBreaker #熔断之后跳转,本项目或其他项目配置

五、限流配置

1、增加依赖

org.springframework.boot:spring-boot-starter-data-redis-reactive

org.springframework.boot:spring-boot-starter-data-redis version: ‘2.5.4’

2、配置redis:spring.redis.database:XX

 spring
     redis:
        host: 1.2.3.4
        port: 6379
        password: redispassword
        pool:
          max-active: 8
          max-wait: -1
          max-idle: 8
          min-idle: 0
        timeout: 30000
        database: 5

3、配置keyResolver,参考类RateLimiteConfig

4、ym配置spring.cloud.gateway.routes

-id: rate-limit-demo
uri: lb://mima-cloud-producer
predicates:
    -Path=/rate/**
filters:
    -name: RequestRateLimiter
     args:
        #令牌桶每秒平均速率,允许用户每秒处理多少个请求
        redis-rate-limiter.replenishRate:1
        #令牌桶的容量,允许在1s内完成的最大请求数
        redis-rate-limiter.burstCapacity:2
        #使用Spel表达式从Spring容器中获取Bean对象,查看RateLimiteConfig实现类中同名方法
        key-resolver: "#{@pathKeyResolver}"
        #key-resolver: "#{@ipKeyResolver}"
        #key-resolver: "#{@userKeyResolver}"

5、当发生限流,会向redis存储两个数据 .限流返回状态码是429

request_rate_limiter.{key}.timestamp

request_rate_limiter.{key}.tokens

timestamp:存储的是当前时间秒数,也就是System.currentTimeMillis()/1000

tokens:存储的当前这秒钟对应的可用令牌数

6、配置文件RateLimiteConfig.java

package com.pig4cloud.pig.demo.controller;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Auther: fengqx
 * @Date: 2022/1/2 - 01 -02 - 22:36
 * @Description: 限流配置
 * @Version: 1.0
 */
@Configuration
public class RateLimiteConfig{

    //ip限流  1s 100次
    //userId限流 1s 100次
    //路径限流
    @Bean
    @Primary  #如果不使用 @Primary 注解,项目启动会报错
    public KeyResolver pathKeyResolver(){
        //写法1
//        return exchange-> Mono.just(
//                exchange.getRequest()
//                .getPath()
//                .toString()
//        );
        //写法2
        return new KeyResolver(){
            @Override
            public Mono<String> resolve(ServerWebExchange exchange){
                return Mono.just(exchange.getRequest()
                .getPath()
                .toString());
            }
        };
    }
    //根据请求IP限流
    @Bean
    public KeyResolver ipKeyResolver(){
        return exchange -> Mono.just(
                exchange.getRequest()
                .getRemoteAddress()
                .getHostName()
        );
    }
    //根据userid限流
    @Bean
    public KeyResolver userKeyResolver(){
        return exchange -> Mono.just(
                exchange.getRequest()
                .getQueryParams()
                .getFirst("userId")
        );
    }
}

六、自定义谓词配置类

可以保存数据库,存储。

1、配置类UserNameCheckRoutePredicateFactory.java

package com.pig4cloud.pig.demo.util;

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

import javax.validation.constraints.NotEmpty;
import java.util.function.Predicate;

/**
 * @Auther: fengqx
 * @Date: 2022/1/2 - 01 -02 - 23:20
 * @Description: 自定义谓词,请求入参包含指定userName
 * @Version: 1.0
 */
@Component
public class UserNameCheckRoutePredicateFactory extends AbstractRoutePredicateFactory<UserNameCheckRoutePredicateFactory.Config> {

    public UserNameCheckRoutePredicateFactory(){
        super(Config.class);
    }
    @Override
    public Predicate<ServerWebExchange> apply(UserNameCheckRoutePredicateFactory.Config config) {
        //写法1
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                String userName = exchange.getRequest().getQueryParams().getFirst("userName");
                if(StringUtils.isNullOrEmpty(userName)){
                    return false;
                }
                //检查请求参数中userName是否与配置的数据相同,如果相同则允许访问,否则不允许访问
                if(userName.equals(config.getName())){
                    return true;
                }
                return false;
            }
        };
    }

    @Validated
    public static class Config{
        @NotEmpty
        private String name;

        public String getName() {
            return name;
        }

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

2、配置项

spring.cloud.gateway
routes:
    -id: Auth_route
     uri: lb://mima-cloud-producer
     order:1
     predicates:
        -Path= /**
        #name配置为UserNameCheckRoutePredicateFactory自定义谓词配置类前缀UserNameCheck, 只有     访问http://192.168.1.10:8081/getheader?userName=Kevin,否则为404
        #必须写在userName请求参数,并且值为kevin
        -name=UserNameCheck
         args:
            name: kevin

七、自定义过滤器

1、配置类

pre配置类

package com.pig4cloud.pig.demo.util;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;

/**
 * @Auther: fengqx
 * @Date: 2022/1/3 - 01 -03 - 10:48
 * @Description: 自定义过滤器 -Pre过滤器
 * @Version: 1.0
 */
@Component
public class MyAddRequestHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory<MyAddRequestHeaderGatewayFilterFactory.Config> {
    public MyAddRequestHeaderGatewayFilterFactory(){super(Config.class);}

    @Override
    public GatewayFilter apply(Config config){
        //写法一
//        return new GatewayFilter() {
//            @Override
//            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//                System.out.println("MyAddRequestHeaderGatewayFilterFactory.apply is run...");
//                //exchange.getRequest().mutate() //目的是转化为装饰类,否则request为只读的,不能操作
//                //header方法用来设置header的值
//                ServerHttpRequest request = exchange.getRequest().mutate().header(config.getName(),config.getValue()).build();
//                //将request包裹继续向下传递
//                return chain.filter(exchange.mutate().request(request).build());
//            }
//        }
        return (exchange, chain) -> {
            System.out.println("MyAddRequestHeaderGatewayFilterFactory.apply is run...");
            //exchange.getRequest().mutate() //目的是转化为装饰类,否则request为只读的,不能操作
            //header方法用来设置header的值
            ServerHttpRequest request=exchange.getRequest().mutate().header(config.getName(),config.getValue()).build();
            return chain.filter(exchange.mutate().request(request).build());
             //response可以直接写
//            exchange.getResponse().getHeaders().set(config.getName(),config.getValue());
//            return chain.filter(exchange);
        };
    }

    @Validated
    public static class Config{
        @NotEmpty
        private String name;
        @NotEmpty
        private String value;

        public String getName() {
            return name;
        }

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

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

post过滤器

@Component
public class PostLogGatewayFilterFactory extends AbstractGatewayFilterFactory {
    @Override
    public GatewayFilter apply(Object config){
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(()-> {
                System.out.println("PostLogGatewayFilterFactory is run...");
            }));
        };
    }
}

3、配置文件

spring.cloud.gateway.routes
-id: MyFilter
uri: lb://mima-cloud
order: 1
predicates:
    -Path=/**
filters:
    -name: MyAddRequestHeader  #Pre过滤器
     args:
        name: req-kevin-header
        value: req-yin.hl
    -name: PostLogGateway  #Post过滤器
效果,所有请求增加一个header

八、全局过滤器

配置文件不需要配置,只需要增加GlobalFilterConfig 类,即可执行到全局过滤

package com.pig4cloud.pig.demo.util;

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import reactor.core.publisher.Mono;

/**
 * @Auther: fengqx
 * @Date: 2022/1/3 - 01 -03 - 21:23
 * @Description: 全局过滤器
 * @Version: 1.0
 */
@Configuration
public class GlobalFilterConfig {
    //order 越小,越先执行
    @Bean
    @Order(-1)
    public GlobalFilter globalFilter1(){
        return (exchange, chain) -> {
            System.out.println("pro filter globalFilter1...");
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                System.out.println("post filter globalFilter1...");
            }));
        };
    }
    @Bean
    @Order(1)
    public GlobalFilter globalFilter2(){
        return (exchange, chain) -> {
            System.out.println("pro filter globalFilter2...");
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                System.out.println("post filter globalFilter2...");
            }));
        };
    }
}

应答顺序为:pro filter globalFilter1…

pro filter globalFilter2…

post filter globalFilter2…

post filter globalFilter1…

九、网关超时配置

spring.cloud.gateway.httpclient.connect-timeout=1000 #连接超时 毫秒

spring.cloud.gateway.httpclient.response-timeout=5s #应答超时 java.time.Duration http状态码504

十、元数据 metadata

十一、gateway内置API与跨域

0、依赖

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'

1、API说明:

/actuator/gateway/routes/{id} ,method=[DELETE] 删除单个路由

/actuator/gateway/routes/{id},method=[POST] 新增单个路由

/actuator/gateway/routes/{id},method=[GET] 查看单个路由

/actuator/gateway/routes ,method=[GET] 查看路由列表

/actuator/gateway/refresh,method=[POST] 路由刷新

/actuator/gateway/globalfilters,method=[GET]获取全局过滤器列表

/actuator/gateway/routefilters,method=[GET] 路由过滤器工厂列表

2、打开端点配置

management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=gateway

3、跨域请求:

配置文件-直接引用即可

package com.pig4cloud.pig.demo.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
/**
 * @Auther: fengqx
 * @Date: 2022/1/3 - 01 -03 - 22:03
 * @Description: 跨域配置
 * http://vvv.mekebin.com/123  ajax-> http://vvv.mekebin.com/123/test 不跨域
 * http://vvv.mekebin.com/123  ajax-> http://def.mekebin.com/123/test 跨域
 * http://vvv.mekebin.com:8801/123  ajax-> http://vvv.mekebin.com:9901/123/test 跨域
 * http://vvv.mekebin.com/123  ajax-> https://vvv.mekebin.com/123/test 跨域
 * @Version: 1.0
 */
@Configuration
public class CorsConfig {
    private static final String MAX_AGE="18000L";
 
    @Bean
    public WebFilter corsFilter(){
        return (ServerWebExchange ctx, WebFilterChain chain)->{
            System.out.println("corsFilter...  run");
            ServerHttpRequest request = ctx.getRequest();
            if(!CorsUtils.isCorsRequest(request)){
                return chain.filter(ctx);
            }
            HttpHeaders requestHeaders=request.getHeaders();
            ServerHttpResponse response = ctx.getResponse();
            HttpMethod requestMethod= requestHeaders.getAccessControlRequestMethod();
            HttpHeaders headers=response.getHeaders();
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestHeaders.getOrigin());
            headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlAllowHeaders());
            if(requestMethod!=null){
                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,requestMethod.name());
            }
            //携带cookie
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
            headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,"*");
            headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
            if(request.getMethod() == HttpMethod.OPTIONS){
                response.setStatusCode(HttpStatus.OK);
                return Mono.empty();
            }
            return chain.filter(ctx);
        };
    }
}

荆轲刺秦王!文章来源地址https://www.toymoban.com/news/detail-433650.html

到了这里,关于SpringCloud Gateway用法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【springcloud 微服务】Spring Cloud 微服务网关Gateway使用详解

    目录 一、微服务网关简介 1.1 网关的作用 1.2 常用网关 1.2.1 传统网关 1.2.2 云原生网关

    2023年04月16日
    浏览(50)
  • SpringCloud OpenFeign 全功能配置详解(一文吃透OpenFeign)

    OpenFeign客户端是一个web声明式http远程调用工具,直接可以根据服务名称去注册中心拿到指定的服务IP集合,提供了接口和注解方式进行调用,内嵌集成了Ribbon本地负载均衡器。 1、底层都是内置了Ribbon,去调用注册中心的服务。 2、Feign是Netflix公司写的,是SpringCloud组件中的一

    2024年02月07日
    浏览(42)
  • Nginx深入:nginx功能模块、目录结构及配置文件详解

    1、Nginx 核心功能模块(Core functionality) Nginx核心功能模块负责Nginx的全局应用,主要对应主配置文件的核心层(Main层)和事件(Events)层,这里有很多 Nginx 必需的全局参数配置。 有关核心功能模块的官方文档为:http://nginx.org/en/docs/ngx_core_module.html 2、标准的 HTTP 功能模块集合

    2024年02月14日
    浏览(45)
  • SpringCloud网关Gateway认证鉴权【SpringCloud系列7】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发 本文章是系列文章中的一篇 1、SpringCloud 项目基础工程搭建 【SpringCloud系列1】 2、S

    2024年02月09日
    浏览(47)
  • SpringCloud-GateWay

    随着微服务架构的盛行,项目由原来的单体系统不断进行演变到现在的微服务,系统被拆分为合适粒度的多个服务,当面临多服务的调用,客户端(发送请求的一段)要如何去调用这么多的微服务呢?如果按照没有使用网关的方式去调用对于客户端是不是就需要知道每一个服

    2024年02月09日
    浏览(44)
  • springcloud gateway动态路由

    动态每秒调用数据库,加载路由信息到路由定义(RouteDefinition)中 主要是继承  RouteDefinitionRepository接口: 如果项目没有自定义的RouteDefinitionRepository 则会加载InMemoryRouteDefinitionRepository 默认将加载的规则存放在内存,加载application.properties文件中配置的路由规则,InMemory加载内

    2024年02月02日
    浏览(37)
  • 【SpringCloud】-GateWay源码解析

    【SpringCloud】-GateWay网关 当一个请求来到 Spring Cloud Gateway 之后,会经过一系列的处理流程,其中涉及到路由的匹配、过滤器链的执行等步骤。今天我们来说说请求经过 Gateway 的主要执行流程和原理是什么吧 下面这张图相信很多学习Gateway的小伙伴都见过的图,在讲述源码之前

    2024年02月03日
    浏览(45)
  • SpringCloud-网关 Gateway

      官方地址:SpringCloud Gateway   网关统一了服务的入口,可以方便实现对众多服务接口进行管控,对访问服务的身份认证,防报文重放与防数据篡改,功能调用的业务鉴权,响应数据的脱敏,流量与并发控制,甚至基于API调用的计量或者计费等等。更通俗理解,网关可以

    2024年02月04日
    浏览(29)
  • 【SpringCloud-5】gateway网关

    网关是干啥用的就不用再说了。 sringcloud中的网关,第一代是zuul,但是性能比较差(1.x是阻塞式的,2.x是基于Netty的),然后有了第二代GateWay,基于Reactor模型 异步非阻塞。  springcloud网关就是一系列的filter,在请求到达真实服务的前后,进行拦截处理。   GateWay 核⼼逻辑:路

    2024年02月09日
    浏览(36)
  • SpringCloud.03.网关Gateway

    目录  网关Gateway的概念: 准备 使用 方式一 因为配置了网关所以可以直接通过gateway发送请求 方式二 修改配置前:http://localhost:8082/provider/run 方式三(动态路由) 导入配置类 Spring Cloud Gateway 是 Spring 官方基于 Spring5.0 、 SpringBoot2.0 和 Project Reactor 等技术开发的网 关 旨在为微服务

    2024年02月01日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包