国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCloud之微服務(wù)API網(wǎng)關(guān)Gateway介紹

這篇具有很好參考價(jià)值的文章主要介紹了SpringCloud之微服務(wù)API網(wǎng)關(guān)Gateway介紹。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1 微服務(wù)API網(wǎng)關(guān)Gateway

1.1 網(wǎng)關(guān)

1.1.1 簡(jiǎn)介

如果沒有網(wǎng)關(guān),難道不行嗎?功能上是可以的,我們直接調(diào)用提供的接口就可以了。那為什么還需要網(wǎng)關(guān)?

因?yàn)榫W(wǎng)關(guān)的作用不僅僅是轉(zhuǎn)發(fā)請(qǐng)求而已。我們可以試想一下,如果需要做一個(gè)請(qǐng)求認(rèn)證功能,我們可以接入到 API 服務(wù)中。但是倘若后續(xù)又有服務(wù)需要接入,我們又需要重復(fù)接入。這樣我們不僅代碼要重復(fù)編寫,而且后期也不利于維護(hù)。

由于接入網(wǎng)關(guān)后,網(wǎng)關(guān)將轉(zhuǎn)發(fā)請(qǐng)求。所以在這一層做請(qǐng)求認(rèn)證,天然合適。這樣這需要編寫一次代碼,在這一層過濾完畢,再轉(zhuǎn)發(fā)給下面的 API。所以 API 網(wǎng)關(guān)的通常作用是完成一些通用的功能,如請(qǐng)求認(rèn)證,請(qǐng)求記錄,請(qǐng)求限流,黑白名單判斷等。

API網(wǎng)關(guān)是一個(gè)服務(wù)器,是系統(tǒng)的唯一入口。
API網(wǎng)關(guān)方式的核心要點(diǎn)是,所有的客戶端和消費(fèi)端都通過統(tǒng)一的網(wǎng)關(guān)接入微服務(wù),在網(wǎng)關(guān)層處理所有的非業(yè)務(wù)功能。通常,網(wǎng)關(guān)提供REST/HTTP的訪問API。

總結(jié)主要作用是:

  • 反向代理(請(qǐng)求的轉(zhuǎn)發(fā))
  • 路由和負(fù)載均衡
  • 身份認(rèn)證和權(quán)限控制
  • 對(duì)請(qǐng)求限流

1.1.2 相比于Zuul

SpringCloudGateway 基于Spring5中提供的WebFlux,是一種響應(yīng)式編程的實(shí)現(xiàn),性能更加優(yōu)越。
Zuul的實(shí)現(xiàn)方式比較老式,基于Servlet的實(shí)現(xiàn),它是一種阻塞式編程,在高并發(fā)下性能性能不佳。

1.2 Spring Cloud Gateway介紹

Spring Cloud GatewaySpring Cloud 的新一代API網(wǎng)關(guān),基于WebFlux框架實(shí)現(xiàn),它旨在為微服務(wù)架構(gòu)提供一種簡(jiǎn)單而有效的統(tǒng)一的API路由管理方式。
Spring Cloud Gateway作為Spring Cloud生態(tài)系統(tǒng)中的網(wǎng)關(guān),目標(biāo)是替代Netflix ZUUL,具有更好的性能、更強(qiáng)的擴(kuò)展性、以及更豐富的功能特性,其不僅提供統(tǒng)一的路由方式,并且基于Filter鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全,監(jiān)控/埋點(diǎn),限流等。

1.3 Gateway特性

Spring Cloud Gateway特性:

  • 基于Spring Framework 5, Project Reactor和Spring Boot 2.0
  • 動(dòng)態(tài)路由:能夠匹配任何請(qǐng)求屬性
  • 可以對(duì)路由指定 Predicate 和 Filter
  • 集成Hystrix斷路器
  • 集成 Spring Cloud DiscoveryClient 服務(wù)發(fā)現(xiàn)功能
  • 易于編寫的Predicate和Filter
  • 請(qǐng)求限流
  • 支持路徑重寫

1.4 Gateway工作流程

客戶端向 Spring Cloud Gateway發(fā)出請(qǐng)求,然后在Gateway Handler Mapping中找到與請(qǐng)求相匹配的路由,將其發(fā)送到 Gateway Web Handler。Handler再通過指定的過濾器鏈來對(duì)請(qǐng)求進(jìn)行過濾處理,最后發(fā)送到我們實(shí)際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回。
SpringCloud之微服務(wù)API網(wǎng)關(guān)Gateway介紹,# SpringCloud,spring cloud,微服務(wù),gateway
過濾器鏈被虛線分隔,是因?yàn)檫^濾器既可以在轉(zhuǎn)發(fā)請(qǐng)求前攔截請(qǐng)求,也可以在請(qǐng)求處理之后對(duì)響應(yīng)進(jìn)行攔截處理。

當(dāng)一個(gè)請(qǐng)求到達(dá)Spring Cloud Gateway時(shí),它的處理順序是:predicates -> uri -> filters

  • predicates負(fù)責(zé)路由的配置斷言,它可以通過PredicateDefinition類進(jìn)行配置
  • uri則是匹配路由的轉(zhuǎn)發(fā)地址,當(dāng)predicates匹配成功后,URI則確定了請(qǐng)求的具體處理地址。
  • 過濾器(Filter)則是對(duì)路由的處理過程進(jìn)行額外的操作,例如添加、刪除或修改請(qǐng)求頭等。這些過濾器可以對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理

1.5 Gateway核心概念

1.5.1 路由

1.5.1.1 定義

路由(Route)是網(wǎng)關(guān)最基礎(chǔ)的部分,路由信息由一個(gè)ID,一個(gè)目標(biāo)URI,一組斷言過濾器組成。
路由斷言Predicate用于匹配請(qǐng)求,過濾器 Filter 用于修改請(qǐng)求和響應(yīng)。如果斷言為true,則說明請(qǐng)求URI和配置匹配,則執(zhí)行路由。

spring:
  cloud:
    gateway:
      # 定義多個(gè)路由
      routes:
      # 一個(gè)路由route的id
      - id: path_route
        # 該路由轉(zhuǎn)發(fā)的目標(biāo)URI
        uri: https://example.org
        # 路由條件集合
        predicates:
        - Path=/test/**
        # 過濾器集合
        filters:
        - AddRequestHeader=X-Request-Id, 1024
        - AddRequestParameter=color, red
1.5.1.2 動(dòng)態(tài)路由

網(wǎng)關(guān)接收外部請(qǐng)求,按照一定的規(guī)則,將請(qǐng)求轉(zhuǎn)發(fā)給其他服務(wù)或者應(yīng)用。如果站在服務(wù)調(diào)用的角度,網(wǎng)關(guān)就扮演著服務(wù)消費(fèi)者的角色,此時(shí),如果再來看看服務(wù)調(diào)用的目標(biāo)URI配置,就會(huì)很自然的發(fā)現(xiàn)一個(gè)問題,服務(wù)提供者調(diào)用的地址是寫死的,即網(wǎng)關(guān)沒有動(dòng)態(tài)的發(fā)現(xiàn)服務(wù),這就涉及到了服務(wù)的自動(dòng)發(fā)現(xiàn)問題,以及發(fā)現(xiàn)服務(wù)后,所涉及到的服務(wù)調(diào)用的負(fù)載均衡的問題。

可以通過Nacos或者Eureka注冊(cè)中心動(dòng)態(tài)發(fā)現(xiàn)服務(wù),通過Ribbon進(jìn)行服務(wù)調(diào)用的負(fù)載均衡。同樣,Gateway也可以整合Nacos或者Eureka,Ribbon從而實(shí)現(xiàn)動(dòng)態(tài)路由的功能。

想要使用動(dòng)態(tài)路由的功能,首先要整合注冊(cè)中心,這里以Nacos為例

pom依賴

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

配置文件

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
        - id: config_route
  #匹配后提供服務(wù)的路由地址, 這里lb之后,跟的是要調(diào)用的服務(wù)名稱
          uri: lb://nacos-provider-8002
  # 斷言,路徑相匹配的條件
          predicates:
            - Path=/routeconfig/rest/**

此時(shí),當(dāng)id為config_route的路由規(guī)則匹配某個(gè)請(qǐng)求后,在調(diào)用該請(qǐng)求對(duì)應(yīng)的服務(wù)時(shí),就會(huì)從nacos注冊(cè)中心自動(dòng)發(fā)現(xiàn)服務(wù),并在服務(wù)調(diào)用的時(shí)候?qū)崿F(xiàn)負(fù)載均衡。

1.5.2 斷言

斷言(Predicate)參考Java8 中的斷言 Predicate ,用于實(shí)現(xiàn)請(qǐng)求匹配邏輯,例如匹配路徑、請(qǐng)求頭、請(qǐng)求參數(shù)等。請(qǐng)求與斷言匹配則執(zhí)行該路由。

Gateway中,有一些的內(nèi)置Predicate Factory,有了這些Pridicate Factory,在運(yùn)行時(shí),Gateway 會(huì)自動(dòng)根據(jù)需要?jiǎng)?chuàng)建其對(duì)應(yīng)的 Pridicate 對(duì)象測(cè)試路由條件。

1.5.2.1 默認(rèn)斷言

Gateway提供的斷言有:Path 路由斷言,After 路由斷言,Cookie 路由斷言,Header 路由斷言 ,Host 路由斷言 ,Method 路由斷言等

名稱 說明 示例
After 某個(gè)時(shí)間點(diǎn)之后的請(qǐng)求 - After=2023-08-01T14:31:20.123-07:00[Asia/Shanghai]
Before 某個(gè)時(shí)間點(diǎn)之前的請(qǐng)求 - Before=2023-08-01T14:31:20.123+08:00[Asia/Shanghai]
Between 某個(gè)時(shí)間點(diǎn)之中的請(qǐng)求 - Before=2023-08-01T14:31:20.123+08:00[Asia/Shanghai],2023-08-05T14:31:20.123+08:00[Asia/Shanghai]
Cookie 請(qǐng)求必須包含某些cookie - Cookie=test
Header 請(qǐng)求必須包含某些header - Header=asd,cas
Host 請(qǐng)求必須包含某個(gè)host(域名) - Host=baidu.com,jd.com
Method 請(qǐng)求必須是指定方式 - Method=GET,POST
Path 請(qǐng)求路徑必須符合指定規(guī)則 - Path=/user/{params},/card/**
Query 請(qǐng)求參數(shù)必須包含指定參數(shù) - Query=name,jack
RemoteAddr 請(qǐng)求者的ip必須是指定范圍 - RemoteAddr=192.168.1.1、24
Weight 權(quán)重處理 - Weight=50

Path 路由斷言 Factory: 根據(jù)請(qǐng)求路徑匹配的路由條件工廠

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        # 如果可以匹配的PathPattern有多個(gè),則每個(gè)路徑模式以,分開
          - Path=/red/{segment},/blue/{segment}

After 路由斷言 Factory: 在指定日期時(shí)間之后發(fā)生的請(qǐng)求都將被匹配

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

Cookie 路由斷言 FactoryCookie 路由斷言 Factory有兩個(gè)參數(shù),cookie名稱和正則表達(dá)式。請(qǐng)求包含此cookie名稱且正則表達(dá)式為真的將會(huì)被匹配。

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

Header 路由斷言 FactoryHeader 路由斷言 Factory有兩個(gè)參數(shù),header名稱和正則表達(dá)式。請(qǐng)求包含此header名稱且正則表達(dá)式為真的將會(huì)被匹配。

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

Host 路由斷言 FactoryHost 路由斷言 Factory包括一個(gè)參數(shù):host name列表。使用Ant路徑匹配規(guī)則, . 作為分隔符。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

Method 路由斷言 FactoryMethod 路由斷言 Factory只包含一個(gè)參數(shù):需要匹配的HTTP請(qǐng)求方式

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET
1.5.2.2 自定義Predicate

可以自定義Predicate來實(shí)現(xiàn)復(fù)雜的路由匹配規(guī)則

實(shí)現(xiàn)自定義 Predicate 工廠
通過HostRoutePredicateFactory創(chuàng)建Predicate進(jìn)行路由判斷
@Component
public class MyHostRoutePredicateFactory extends AbstractRoutePredicateFactory<MyHostRoutePredicateFactory.Config> {

  public MyHostRoutePredicateFactory() {
      // Config 類作為 Predicate 的配置參數(shù)類
      super(Config.class);
  }
  public static class Config {
      // 路由匹配規(guī)則
      private String hostName;

      public String getHostName() {
        return hostName;
      }

      public void setHostName(String hostName) {
        this.hostName = hostName; 
      }
  }
  // 生成一個(gè) Predicate 實(shí)例
  @Override
  public Predicate<ServerWebExchange> apply(Config config) {
      // 實(shí)現(xiàn)匹配邏輯
      return exchange -> {
          // 根據(jù)config實(shí)現(xiàn)匹配判斷         
          String host = exchange.getRequest().getURI().getHost();
          // 匹配配置中的域名
          return host.equals(config.getHostName());
      };
  } 
}

使用

RouteLocator locator = new RouteLocatorBuilder(router)
  .routes()
  .route("test_route", r -> r.path("/test")
  .filters(f -> f.filter(new MyHostRoutePredicateFactory.Config("www.test.com")))
  .uri("http://localhost:8080"))
  .build();

1.5.3 過濾器

過濾器(Filter) 指的是Spring框架中GatewayFilter的實(shí)例,使用過濾器,可以在請(qǐng)求被路由前后對(duì)請(qǐng)求進(jìn)行修改

1.5.3.1 默認(rèn)過濾器

配置文件中添加過濾器 filters

filters:
	- AddRequestHeader=name,zs          #請(qǐng)求頭添加name:zs
	- RemoveRequestHeader=name          #移除請(qǐng)求中一個(gè)請(qǐng)求頭
	- AddRequestParameter=color,blue    #請(qǐng)求參數(shù)添加color:blue
	- AddResponseHeader=phone,973345344 #響應(yīng)頭添加phone:973345344
	- RemoveResponseHeader=phone,973345344 #響應(yīng)頭移除一個(gè)響應(yīng)頭phone
	- PrefixPath=/mypath			    #添加路徑前綴/mypath
	- StripPrefix=n					    #刪除路徑前綴n個(gè)
	- RequestRateLimiter=n				 #限制請(qǐng)求流量

Spring Cloud Gateway內(nèi)置的多種過濾器類,例如:

  • AddRequestHeader GatewayFilter:在請(qǐng)求頭中添加參數(shù)
  • PrefixPath GatewayFilter:請(qǐng)求路徑前綴
  • Hystrix GatewayFilter:斷路器
  • RateLimit GatewayFilter:限流
  • Retry GatewayFilter:重試
1.5.3.2 局部過濾器
spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters:         # 過濾器配置
        - AddRequestHeader=token, test # 添加請(qǐng)求頭

上述過濾器的含義:

  • 給所有進(jìn)入userservice的請(qǐng)求添加一個(gè)請(qǐng)求頭。
  • 請(qǐng)求頭的key為token,value為test。
  • 由于當(dāng)前前過濾器寫在微服務(wù)的userservice路由下,因此僅僅對(duì)訪問微服務(wù)userservice的請(qǐng)求有效。
1.5.3.3 全局過濾器
spring:
  cloud:
    gateway:
      routes:
        - id: user-service 
          uri: lb://userservice 
          predicates: 
          - Path=/user/**
      default-filters:      # 默認(rèn)過濾器配置
        - AddRequestHeader=token, test  # 添加請(qǐng)求頭

default-filters 的配置和 routes平級(jí)。
只要配置在 default-filters 下面的過濾器,會(huì)對(duì) routes 配置的所有路由都生效。

1.5.3.4 自定義過濾器
1.5.3.4.1 GatewayFilter

可以通過實(shí)現(xiàn)GatewayFilterOrdered接口自定義Filter來實(shí)現(xiàn)請(qǐng)求處理邏輯:

@Component
public class TokenFilter implements GatewayFilter, Ordered {

   @Override
   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      //請(qǐng)求處理邏輯
      log.info("請(qǐng)求路徑:"+ exchange.getRequest().getPath());
      
      ServerHttpRequest request = exchange.getRequest();
   MultiValueMap<String, HttpCookie> cookies = request.getCookies();
   List<HttpCookie> tokens = cookies.get("access_token");
   if (tokens == null || tokens.size() == 0) {
      throw new RuntimeException("少了cookie!");
   }
      
      return chain.filter(exchange);
   }

   @Override
   public int getOrder() {
      return 0; 
   }
}

當(dāng)有多個(gè)過濾器時(shí),Order的值決定了過濾器的執(zhí)行順序。

數(shù)值越大優(yōu)先級(jí)越低, 負(fù)的越多, 優(yōu)先級(jí)越高

設(shè)置Order的值有兩種方式:

  • 實(shí)現(xiàn)Ordered接口,并且重寫getOrder方法
  • 使用@Order注解
1.5.3.4.2 GlobalFilter
public class MyFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.獲取請(qǐng)求參數(shù) 
        //1.這里的request并不是servlet中的request  
        //2.返回值是一個(gè)多鍵的map集合、也就是說這個(gè)map集合的鍵可以重復(fù)
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.獲取userName參數(shù)
        String userName = params.getFirst("userName");
        // 3.校驗(yàn)
        if ("root".equals(userName)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.攔截
        // 4.1.禁止訪問,設(shè)置狀態(tài)碼
        exchange.getResponse().setStatusCode(500);
        // 4.2.結(jié)束處理
        return exchange.getResponse().setComplete();
    }
}
1.5.3.4.3 AbstractGatewayFilterFactory

通過繼承AbstractGatewayFilterFactory來實(shí)現(xiàn)

public class DemoGatewayFilterFactory extends AbstractGatewayFilterFactory<DemoGatewayFilterFactory.Config> {
    @Override
    public GatewayFilter apply(Config config) {
        return null;
    }
    //Config 靜態(tài)內(nèi)部類,負(fù)責(zé)指定網(wǎng)關(guān)的參數(shù)
    static class Config{
    	private String arg1;
    }
}

注意DemoGatewayFilterFactory 的命名方式:由Demo + GatewayFilterFactory組成,
其中Demo是自己起名字,GatewayFilterFactory是固定的。
范型中的Config是我們待會(huì)要用到的靜態(tài)內(nèi)部類,用于聲明過濾器中傳遞的參數(shù)

Spring Cloud Gateway中,自定義的過濾器會(huì)在全局過濾器鏈中生效,不需要顯式配置在路由配置中。這是因?yàn)?code>AbstractGatewayFilterFactory類已經(jīng)實(shí)現(xiàn)了GatewayFilterFactory接口,并且通過Spring的自動(dòng)裝配機(jī)制將其注冊(cè)到全局過濾器鏈中,并且可以在任何路由上生效。

需要注意的是,在全局過濾器鏈中的順序是根據(jù)Spring Bean加載順序決定的??梢酝ㄟ^設(shè)置@Order注解或?qū)崿F(xiàn)Ordered接口來控制自定義過濾器在全局過濾器鏈中的順序。

1.5.3.5 過濾路由過濾器的執(zhí)行順序

由上面可知 SpringCloudGateWay 中,有三種過濾器:

  • 默認(rèn)過濾器 default-filters
  • 只對(duì)具體某個(gè)路由生效的局部過濾器filters
  • 使用java代碼編寫的自定義全局過濾器GlobalFilter

SpringCloud之微服務(wù)API網(wǎng)關(guān)Gateway介紹,# SpringCloud,spring cloud,微服務(wù),gateway
過濾器的執(zhí)行順序?yàn)椋耗J(rèn)過濾器 → 當(dāng)前路由過濾器 → 自定義全局過濾器

1.6 實(shí)際操作

1.6.1 pom.xml

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

1.6.2 啟動(dòng)類

@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {

 public static void main(String[] args) {
  SpringApplication.run(GatewayApplication.class, args);
 }
}

1.6.3 配置文件 application.yml

spring: 
  application:
    name: cloud-gateway 
  cloud:
    gateway:
      routes:
      # 路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
      - id: config_route
       # 匹配后提供服務(wù)的路由地址
        uri: http://ityouknow.com
        # 斷言,路徑相匹配的條件
        predicates:
        - Path=/routeconfig/rest/**
      - id: header_route
        uri: http://ityouknow.com
        predicates:
        - Header=X-Request-Id, \d+

1.7 跨域處理

1.7.1 跨域的概念和原理

跨域:請(qǐng)求位置和被請(qǐng)求位置不同源就會(huì)發(fā)生跨域。
這里的不同源包括兩個(gè)點(diǎn):

  • 域名不同:www.baidu.com 和 www.taobao.com。(IP不同也是相同道理)
  • 端口不同:127.0.0.1:8080和127.0.0.1:8081。

而瀏覽器又會(huì)禁止請(qǐng)求的發(fā)起者與服務(wù)端發(fā)生跨域AJAX請(qǐng)求。
如果發(fā)生了跨域請(qǐng)求,服務(wù)器端是能夠正常響應(yīng)的,但是響應(yīng)的結(jié)果會(huì)被瀏覽器攔截。

1.7.2 跨域常見解決方案

使用CORS方式。
CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。
它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。

1.7.3 gateway中如何解決跨域問題

1.7.3.1 配置文件

配置application.yml文件:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域配置
        add-to-simple-url-handler-mapping: true # 解決options請(qǐng)求被攔截問題
               # options請(qǐng)求 就是一種詢問服務(wù)器是否瀏覽器可以跨域的請(qǐng)求
               # 如果每次跨域都有詢問服務(wù)器是否瀏覽器可以跨域?qū)π阅芤彩菗p耗
               # 可以配置本次跨域檢測(cè)的有效期maxAge
               # 在maxAge設(shè)置的時(shí)間范圍內(nèi),不去詢問,統(tǒng)統(tǒng)允許跨域
        corsConfigurations:
          '[/**]': # 這里的'/**'表示對(duì)所有路由生效,可以根據(jù)需要調(diào)整為特定路徑
            allowedOrigins:   # 允許哪些網(wǎng)站的跨域請(qǐng)求 
              - "http://localhost:8090"
            allowedMethods:   # 允許的跨域ajax的請(qǐng)求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*"  # 允許在請(qǐng)求中攜帶的頭信息
            allowCredentials: true # 允許在請(qǐng)求中攜帶cookie
            maxAge: 360000    # 本次跨域檢測(cè)的有效期(單位毫秒)
                  # 有效期內(nèi),跨域請(qǐng)求不會(huì)一直發(fā)option請(qǐng)求去增大服務(wù)器壓力
1.7.3.2 編碼
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;

@Configuration
public class CorsConfig {
    private static final String MAX_AGE = "18000L";

    @Bean
    public WebFilter corsFilter() {
        return (ServerWebExchange ctx, WebFilterChain chain) -> {
            ServerHttpRequest request = ctx.getRequest();
            // 使用SpringMvc自帶的跨域檢測(cè)工具類判斷當(dāng)前請(qǐng)求是否跨域
            if (!CorsUtils.isCorsRequest(request)) {
                return chain.filter(ctx);
            }
            HttpHeaders requestHeaders = request.getHeaders();                                  // 獲取請(qǐng)求頭
            ServerHttpResponse response = ctx.getResponse();                                    // 獲取響應(yīng)對(duì)象
            HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();          // 獲取請(qǐng)求方式對(duì)象
            HttpHeaders headers = response.getHeaders();                                        // 獲取響應(yīng)頭
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());   // 把請(qǐng)求頭中的請(qǐng)求源(協(xié)議+ip+端口)添加到響應(yīng)頭中(相當(dāng)于yml中的allowedOrigins)
            headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
            if (requestMethod != null) {
                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());    // 允許被響應(yīng)的方法(GET/POST等,相當(dāng)于yml中的allowedMethods)
            }
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");          // 允許在請(qǐng)求中攜帶cookie(相當(dāng)于yml中的allowCredentials)
            headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");                // 允許在請(qǐng)求中攜帶的頭信息(相當(dāng)于yml中的allowedHeaders)
            headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);                           // 本次跨域檢測(cè)的有效期(單位毫秒,相當(dāng)于yml中的maxAge)
            if (request.getMethod() == HttpMethod.OPTIONS) {                                    // 直接給option請(qǐng)求反回結(jié)果
                response.setStatusCode(HttpStatus.OK);
                return Mono.empty();
            }
            return chain.filter(ctx);                                                           // 不是option請(qǐng)求則放行
        };
    }

}

Spring-Framework 從 5.3 版本之前,使用以下代碼可以讓 Spring Cloud Gateway 網(wǎng)關(guān)允許跨域:

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 這里僅為了說明問題,配置為放行所有域名,生產(chǎn)環(huán)境請(qǐng)對(duì)此進(jìn)行修改
        config.addAllowedOrigin("*");
        // 放行的請(qǐng)求頭
        config.addAllowedHeader("*");
        // 放行的請(qǐng)求類型,有 GET, POST, PUT, DELETE, OPTIONS
        config.addAllowedMethod("*"); 
        // 暴露頭部信息
        config.addExposedHeader("*"); 
        // 是否允許發(fā)送 Cookie
        config.setAllowCredentials(true); 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

Spring-Framework 5.3 版本之后,關(guān)于 CORS 跨域配置類 CorsConfiguration 中將 addAllowedOrigin 方法名修改為 addAllowedOriginPattern,因此配置了變成了以下這樣:

@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 這里僅為了說明問題,配置為放行所有域名,生產(chǎn)環(huán)境請(qǐng)對(duì)此進(jìn)行修改
        config.addAllowedOriginPattern("*");
        // 放行的請(qǐng)求頭
        config.addAllowedHeader("*");
        // 放行的請(qǐng)求類型,有 GET, POST, PUT, DELETE, OPTIONS
        config.addAllowedMethod("*"); 
        // 暴露頭部信息
        config.addExposedHeader("*"); 
        // 是否允許發(fā)送 Cookie
        config.setAllowCredentials(true); 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

1.8 json配置

Spring Cloud Gateway 框架中斷言(Predicate)類型除了 Yaml 文件外還有 JSON 數(shù)據(jù)格式中的配置進(jìn)行整理。其中 JSON 格式數(shù)據(jù)類型在動(dòng)態(tài)路由時(shí)需使用到,如動(dòng)態(tài)讀取數(shù)據(jù)庫(kù)中保存的 JSON 格式的路由數(shù)據(jù)。

如下:Yaml配置文件

spring:  
  cloud:  
    gateway:  
      routes:  
      - id: path_route  
        uri: http://127.0.0.1:8080  
        predicates:  
        - Path=/server-a/**,/server-b/**
        - Method=GET,POST

動(dòng)態(tài)路由的JSON格式

{  
    "id": "path_route",  
    "uri": "http://127.0.0.1:8082",  
    "predicates":[  
        {  
            "name": "Path",  
            "args": {   
                "_genkey_0": "/server-a/**",  
                "_genkey_1": "/server-b/**"  
            }  
        },{  
            "name": "Method",  
            "args": {   
                "_genkey_0": "GET",  
                "_genkey_1": "POST"
        }
 
    ]  
}

其中args中值對(duì)應(yīng)的key,即_genkey_0可以任意定義值,查看源碼讀取該配置可知,源碼通過args.values()獲取配置的所有值,所以此處key的命名可任意命名。

參考連接:
https://mp.weixin.qq.com/s/LY66FPCajHkzXJUFlfSNYg
https://blog.csdn.net/h1774733219/article/details/124384527
https://blog.csdn.net/qq_46203643/article/details/127150590
https://mp.weixin.qq.com/s/Y6M1GzrIOBOz6fM12b0uPw文章來源地址http://www.zghlxwxcb.cn/news/detail-625203.html

到了這里,關(guān)于SpringCloud之微服務(wù)API網(wǎng)關(guān)Gateway介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Cloud Gateway:新一代微服務(wù) API 網(wǎng)關(guān),用起來真優(yōu)雅!

    Spring Cloud Gateway:新一代微服務(wù) API 網(wǎng)關(guān),用起來真優(yōu)雅!

    如果沒有網(wǎng)關(guān),難道不行嗎?功能上是可以的,我們直接調(diào)用提供的接口就可以了。那為什么還需要網(wǎng)關(guān)? 因?yàn)榫W(wǎng)關(guān)的作用不僅僅是轉(zhuǎn)發(fā)請(qǐng)求而已。我們可以試想一下,如果需要做一個(gè)請(qǐng)求認(rèn)證功能,我們可以接入到 API 服務(wù)中。但是倘若后續(xù)又有服務(wù)需要接入,我們又需要

    2024年02月09日
    瀏覽(28)
  • Spring Cloud之API網(wǎng)關(guān)(Gateway)

    Spring Cloud之API網(wǎng)關(guān)(Gateway)

    目錄 API網(wǎng)關(guān) 好處 解決方案 Gateway 簡(jiǎn)介 特征 核心概念 Route(路由) Predicate(斷言) Filter(過濾器) 工作流程 Route(路由) 路由配置方式 1.yml配置文件路由 2.bean進(jìn)行配置 3.動(dòng)態(tài)路由 動(dòng)態(tài)路由 Predicate(斷言) 特點(diǎn) 常見斷言 示例 Filter(過濾器) filter分類 Pre 類型 Post 類型 網(wǎng)關(guān)過濾器 格式

    2024年02月08日
    瀏覽(31)
  • SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān),Route路由,Predicate 謂詞/斷言,F(xiàn)ilter 過濾器(十三)

    SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān),Route路由,Predicate 謂詞/斷言,F(xiàn)ilter 過濾器(十三)

    閱讀本文前可先參考 ??????SpringCloud - Spring Cloud根/父項(xiàng)目,開發(fā)準(zhǔn)備(二)_MinggeQingchun的博客-CSDN博客 SpringCloud - Spring Cloud 之 Gateway網(wǎng)關(guān)(十三)_MinggeQingchun的博客-CSDN博客 Web 有三大組件(監(jiān)聽器 過濾器 servlet),Spring Cloud GateWay 最主要的功能就是路由轉(zhuǎn)發(fā),而在定義

    2024年02月14日
    瀏覽(29)
  • Spring cloud教程Gateway服務(wù)網(wǎng)關(guān)

    Spring cloud教程Gateway服務(wù)網(wǎng)關(guān)

    寫在前面的話: 本筆記在參考網(wǎng)上視頻以及博客的基礎(chǔ)上,只做個(gè)人學(xué)習(xí)筆記,如有侵權(quán),請(qǐng)聯(lián)系刪除,謝謝! Spring Cloud Gateway 是 Spring Cloud 的一個(gè)全新項(xiàng)目,該項(xiàng)目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等響應(yīng)式編程和事件流技術(shù)開發(fā)的網(wǎng)關(guān),它旨在為微服務(wù)架構(gòu)提

    2024年02月08日
    瀏覽(31)
  • Spring Cloud第二季--服務(wù)網(wǎng)關(guān)Gateway

    Spring Cloud第二季--服務(wù)網(wǎng)關(guān)Gateway

    Spring Cloud Gateway是在Spring生態(tài)系統(tǒng)之上構(gòu)建的API網(wǎng)關(guān)服務(wù),基于Spring 5,Spring Boot 2和 Project Reactor等技術(shù)。 Gateway 使用的Webflux中的reactor-netty響應(yīng)式編程組件,底層使用了 Netty 通訊框架。Spring Cloud Gateway能干嘛呢? Gateway是原zuul1.x版的替代。 Spring Cloud Gateway 與 Zuul的區(qū)別: Zuu

    2024年02月03日
    瀏覽(24)
  • 【SpringCloud技術(shù)專題】「Gateway網(wǎng)關(guān)系列」(1)微服務(wù)網(wǎng)關(guān)服務(wù)的Gateway組件的原理介紹分析

    【SpringCloud技術(shù)專題】「Gateway網(wǎng)關(guān)系列」(1)微服務(wù)網(wǎng)關(guān)服務(wù)的Gateway組件的原理介紹分析

    為什么要有服務(wù)網(wǎng)關(guān)? 我們都知道在微服務(wù)架構(gòu)中,系統(tǒng)會(huì)被拆分為很多個(gè)微服務(wù)。那么作為客戶端要如何去調(diào)用這么多的微服務(wù)呢?難道要一個(gè)個(gè)的去調(diào)用嗎?很顯然這是不太實(shí)際的,我們需要有一個(gè)統(tǒng)一的接口與這些微服務(wù)打交道,這就是我們需要服務(wù)網(wǎng)關(guān)的原因。 我們

    2024年02月11日
    瀏覽(32)
  • springboot整合spring cloud gateway搭建網(wǎng)關(guān)服務(wù)

    springboot整合spring cloud gateway搭建網(wǎng)關(guān)服務(wù)

    spring cloud netflix zuul、spring cloud gateway是最常見的微服務(wù)網(wǎng)關(guān),通過網(wǎng)關(guān),我們可以在請(qǐng)求到達(dá)后端指定服務(wù)之前/后端服務(wù)處理完業(yè)務(wù)響應(yīng)數(shù)據(jù)之后對(duì)響應(yīng)進(jìn)行對(duì)請(qǐng)求/響應(yīng)進(jìn)行處理。 比如常見的參數(shù)校驗(yàn)、接口鑒權(quán)等等,在后端服務(wù)的攔截器和過濾器能做的事在網(wǎng)關(guān)都可以做

    2024年02月07日
    瀏覽(25)
  • 微服務(wù)·架構(gòu)組件之網(wǎng)關(guān)- Spring Cloud Gateway

    微服務(wù)·架構(gòu)組件之網(wǎng)關(guān)- Spring Cloud Gateway

    微服務(wù)架構(gòu)已成為構(gòu)建現(xiàn)代化應(yīng)用程序的關(guān)鍵范式之一,它將應(yīng)用程序拆分成多個(gè)小型、可獨(dú)立部署的服務(wù)。Spring Cloud Gateway是Spring Cloud生態(tài)系統(tǒng)中的一個(gè)關(guān)鍵組件,用于構(gòu)建和管理微服務(wù)架構(gòu)中的網(wǎng)關(guān)。本報(bào)告旨在調(diào)查和介紹Spring Cloud Gateway的核心概念、架構(gòu)、功能以及其在

    2024年02月09日
    瀏覽(24)
  • 微服務(wù)網(wǎng)關(guān):Spring Cloud Zuul 升級(jí) Spring Cloud Gateway 的核心要點(diǎn)

    微服務(wù)網(wǎng)關(guān):Spring Cloud Zuul 升級(jí) Spring Cloud Gateway 的核心要點(diǎn)

    在routes路由規(guī)則中,根據(jù)path去匹配,如果匹配中,就使用對(duì)應(yīng)的路由規(guī)則進(jìn)行請(qǐng)求轉(zhuǎn)發(fā) 如果無法從routes中匹配,則根據(jù)path用“/”去截取第一段作為服務(wù)名進(jìn)行請(qǐng)求轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)時(shí),默認(rèn)將第一段截取調(diào) 如果截取的服務(wù)名不在注冊(cè)中心中存在服務(wù),則報(bào)錯(cuò)404 在routes路由規(guī)則中

    2024年02月07日
    瀏覽(27)
  • Eureka上集成Spring Cloud 微服務(wù)網(wǎng)關(guān) gateway

    Eureka上集成Spring Cloud 微服務(wù)網(wǎng)關(guān) gateway

    第一章 Java線程池技術(shù)應(yīng)用 第二章 CountDownLatch和Semaphone的應(yīng)用 第三章 Spring Cloud 簡(jiǎn)介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay API 網(wǎng)關(guān)是一個(gè)搭建在客戶端和微服務(wù)之間的服務(wù),我們可以在 API 網(wǎng)關(guān)中

    2024年02月08日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包