最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot使用Gateway做網(wǎng)關(guān)并且配置全局?jǐn)r截器的方式

 更新時(shí)間:2025年02月11日 10:37:39   作者:用草書(shū)譜寫(xiě)蘭亭序  
本文介紹了Spring Cloud Gateway的使用,包括為什么需要使用網(wǎng)關(guān)、如何簡(jiǎn)單使用、斷言工廠(chǎng)路由、路由過(guò)濾器、全局過(guò)濾器以及跨域請(qǐng)求配置,感興趣的朋友一起看看吧

一、為什么要用網(wǎng)關(guān)

統(tǒng)一入口:

  • 作用:作為所有客戶(hù)端請(qǐng)求的統(tǒng)一入口。
  • 說(shuō)明:所有客戶(hù)端請(qǐng)求都通過(guò)網(wǎng)關(guān)進(jìn)行路由,網(wǎng)關(guān)負(fù)責(zé)將請(qǐng)求轉(zhuǎn)發(fā)到后端的微服務(wù)

路由轉(zhuǎn)發(fā):

  • 作用:根據(jù)請(qǐng)求的URL、方法等信息將請(qǐng)求路由到不同的微服務(wù)。
  • 說(shuō)明:網(wǎng)關(guān)可以根據(jù)配置的路由規(guī)則,將請(qǐng)求轉(zhuǎn)發(fā)到正確的微服務(wù),實(shí)現(xiàn)請(qǐng)求的路由和負(fù)載均衡。

負(fù)載均衡:

  • 作用:實(shí)現(xiàn)請(qǐng)求的負(fù)載均衡。
  • 說(shuō)明:網(wǎng)關(guān)可以集成負(fù)載均衡組件(如Ribbon),根據(jù)負(fù)載均衡策略將請(qǐng)求分發(fā)到不同的服務(wù)實(shí)例,提高系統(tǒng)的可用性和擴(kuò)展性。

服務(wù)發(fā)現(xiàn):

  • 作用:與服務(wù)注冊(cè)中心集成,實(shí)現(xiàn)服務(wù)的自動(dòng)發(fā)現(xiàn)。
  • 說(shuō)明:網(wǎng)關(guān)可以與Eureka等服務(wù)注冊(cè)中心集成,動(dòng)態(tài)獲取服務(wù)實(shí)例的信息,實(shí)現(xiàn)服務(wù)的自動(dòng)發(fā)現(xiàn)和路由。

認(rèn)證與授權(quán):

  • 作用:提供統(tǒng)一的安全認(rèn)證和授權(quán)機(jī)制。
  • 說(shuō)明:網(wǎng)關(guān)可以集成認(rèn)證和授權(quán)組件(如OAuth2、JWT),對(duì)所有進(jìn)入的請(qǐng)求進(jìn)行安全檢查,確保只有合法的請(qǐng)求才能訪(fǎng)問(wèn)后端服務(wù)。

跨域資源共享(CORS):

  • 作用:處理跨域請(qǐng)求。
  • 說(shuō)明:網(wǎng)關(guān)可以處理跨域請(qǐng)求,允許來(lái)自不同域的客戶(hù)端訪(fǎng)問(wèn)后端服務(wù),解決了瀏覽器的同源策略限制。

二、Gateway簡(jiǎn)單使用

第一步:引入Gateway的maven依賴(lài)到pom.xml文件

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

第二步:編寫(xiě)配置文件application.yml文件,如下所示:

server:
  port: 10086   # 網(wǎng)關(guān)端口
spring:
  application:
    name: gateway # 服務(wù)名稱(chēng)
  cloud:
    nacos:
      server-addr: localhost:8848    # nacos 地址
    gateway:
      routes:         # 網(wǎng)關(guān)路由配置
        - id: provider      # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081   # 路由的目標(biāo)地址 (直接寫(xiě)死地址的方式,不推薦)
          uri: lb://provider    # 路由的目標(biāo)地址 lb是負(fù)載均衡,后面跟服務(wù)名稱(chēng)(推薦)
          predicates:       # 路由斷言,判斷請(qǐng)求是否符合路由規(guī)則的條件
            - Path=/provider/**      # 按照路徑匹配,以/user/開(kāi)頭的請(qǐng)求就符合要求

第三步:?jiǎn)?dòng)測(cè)試

當(dāng)然要注意的是我們需要開(kāi)啟另一個(gè)服務(wù)provider服務(wù),并且這個(gè)服務(wù)需要配置方法前綴/provider,當(dāng)我們通過(guò)網(wǎng)關(guān)訪(fǎng)問(wèn)的時(shí)候就可以直接的訪(fǎng)問(wèn)到provider服務(wù)了。

三、Gateway斷言工廠(chǎng)

路由斷言主要用來(lái)判斷路由的規(guī)則。

配置文件中寫(xiě)的斷言規(guī)則只是字符串,這些字符串會(huì)被Predicate Factory讀取并處理。

例如Path=/user/**是按照路徑匹配,這個(gè)規(guī)則是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory類(lèi)來(lái)處理。

像這樣的斷言工廠(chǎng)在SpringCloudGateway還有十幾個(gè):

當(dāng)然這個(gè)地方可能給的不是很全所以我貼出官網(wǎng)地址:大家需要的可以去看官網(wǎng):Spring Cloud Gateway

https://docs.spring.io/spring-cloud-gateway/docs/3.1.4-SNAPSHOT/reference/html/#gateway-request-predicates-factories

簡(jiǎn)單示例,下面我配置一個(gè)在訪(fǎng)問(wèn)之前需要到一定的時(shí)間才可以訪(fǎng)問(wèn),并且看一下效果

server:
  port: 10086   # 網(wǎng)關(guān)端口
spring:
  application:
    name: gateway # 服務(wù)名稱(chēng)
  cloud:
    nacos:
      server-addr: localhost:8848    # nacos 地址
    gateway:
      routes:         # 網(wǎng)關(guān)路由配置
        - id: provider      # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081   # 路由的目標(biāo)地址 (直接寫(xiě)死地址的方式,不推薦)
          uri: lb://provider    # 路由的目標(biāo)地址 lb是負(fù)載均衡,后面跟服務(wù)名稱(chēng)(推薦)
          predicates:       # 路由斷言,判斷請(qǐng)求是否符合路由規(guī)則的條件
            - Path=/provider/**      # 按照路徑匹配,以/user/開(kāi)頭的請(qǐng)求就符合要求
            - After=2031-01-20T17:42:47.789-07:00[America/Denver]

因?yàn)槲遗渲昧诵枰?031年1月20號(hào)后才可以訪(fǎng)問(wèn)明顯現(xiàn)在是2024年不可以訪(fǎng)問(wèn)到,所以會(huì)報(bào)錯(cuò)404。

四、Gateway路由過(guò)濾器

客戶(hù)端請(qǐng)求先找到路由,路由匹配時(shí)經(jīng)過(guò)過(guò)濾器層層篩選,最終訪(fǎng)問(wèn)到微服務(wù)。

當(dāng)然微服務(wù)的請(qǐng)求反悔時(shí),也會(huì)經(jīng)過(guò)過(guò)濾器的篩選,只不過(guò)我們一般只對(duì)請(qǐng)求過(guò)濾,而不會(huì)對(duì)響應(yīng)過(guò)濾。

SpringCloudGateWay目前已經(jīng)提供了34種不同的過(guò)濾器工廠(chǎng)。感興趣的大家也可以去上面給出的官網(wǎng)地址查看。

下面我在路由過(guò)濾器中添加一個(gè)請(qǐng)求頭,并且需要在provider請(qǐng)求中加入一個(gè)參數(shù)去拿到請(qǐng)求頭中的參數(shù)

server:
  port: 10086   # 網(wǎng)關(guān)端口
spring:
  application:
    name: gateway # 服務(wù)名稱(chēng)
  cloud:
    nacos:
      server-addr: localhost:8848    # nacos 地址
    gateway:
      routes:         # 網(wǎng)關(guān)路由配置
        - id: provider      # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081   # 路由的目標(biāo)地址 (直接寫(xiě)死地址的方式,不推薦)
          uri: lb://provider    # 路由的目標(biāo)地址 lb是負(fù)載均衡,后面跟服務(wù)名稱(chēng)(推薦)
          predicates:       # 路由斷言,判斷請(qǐng)求是否符合路由規(guī)則的條件
            - Path=/provider/**      # 按照路徑匹配,以/user/開(kāi)頭的請(qǐng)求就符合要求
          filters: # 過(guò)濾器配置
            - AddRequestHeader=token, test # 添加請(qǐng)求頭

provider請(qǐng)求變?yōu)椋枰玫秸?qǐng)求頭中的信息

    @GetMapping("/provider/t")
    public String t(@RequestHeader(value = "token",required = false)String token){
        return "恭喜您測(cè)試成功啦!"+token;
    }

測(cè)試

當(dāng)然這是局部配置我們也可以針對(duì)所有的路由進(jìn)行全局配置(但是這個(gè)配置是需要和路由s是同級(jí)的),如下所示:

server:
  port: 10086   # 網(wǎng)關(guān)端口
spring:
  application:
    name: gateway # 服務(wù)名稱(chēng)
  cloud:
    nacos:
      server-addr: localhost:8848    # nacos 地址
    gateway:
      routes:         # 網(wǎng)關(guān)路由配置
        - id: provider      # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081   # 路由的目標(biāo)地址 (直接寫(xiě)死地址的方式,不推薦)
          uri: lb://provider    # 路由的目標(biāo)地址 lb是負(fù)載均衡,后面跟服務(wù)名稱(chēng)(推薦)
          predicates:       # 路由斷言,判斷請(qǐng)求是否符合路由規(guī)則的條件
            - Path=/provider/**      # 按照路徑匹配,以/user/開(kāi)頭的請(qǐng)求就符合要求
      default-filters: # 默認(rèn)過(guò)濾器配置
        - AddRequestHeader=token, test  # 添加請(qǐng)求頭

五、Gateway全局過(guò)濾器

上面的gateway路由器可以配置全局的,為什么還需要有一個(gè)全局過(guò)濾器呢,因?yàn)樯厦娴倪^(guò)濾器都是只可以針對(duì)與一些邏輯的攔截,但是不可以涉及到一些業(yè)務(wù)的處理,所以就有這個(gè)全局過(guò)濾器可以通過(guò)編寫(xiě)代碼的方式來(lái)編寫(xiě)業(yè)務(wù)邏輯進(jìn)行對(duì)用戶(hù)訪(fǎng)問(wèn)的鑒權(quán)放行等等。

package com.example.demo.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.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class GateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // 1.獲取請(qǐng)求參數(shù)
                //1.這里的request并不是servlet中的request
                //2.返回值是一個(gè)多鍵的map集合、也就是說(shuō)這個(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.禁止訪(fǎng)問(wèn),設(shè)置狀態(tài)碼
                exchange.getResponse().setStatusCode(HttpStatus.valueOf(500));
                // 4.2.結(jié)束處理
                return exchange.getResponse().setComplete();
    }
    //過(guò)濾器優(yōu)先級(jí),數(shù)字越小優(yōu)先級(jí)越高
    @Override
    public int getOrder() {
        return -1;
    }
}

測(cè)試:

我們先正常的訪(fǎng)問(wèn)之前的請(qǐng)求,會(huì)發(fā)現(xiàn)無(wú)法使用此頁(yè)面也就是被拒絕訪(fǎng)問(wèn)了

當(dāng)我們加上一個(gè)參數(shù)后把userName=root加上之后就可以正確的訪(fǎng)問(wèn)到請(qǐng)求了

過(guò)濾器鏈執(zhí)行順序

SpringCloudGateWay中,有三種過(guò)濾器:

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

過(guò)濾器最終都會(huì)轉(zhuǎn)化成GlobalFilter(使用的是適配器模式)所以我們就可以把這三種過(guò)濾器看成一個(gè)整體而順序也入下圖顯示的一致。

由上圖知過(guò)濾器的執(zhí)行順序?yàn)椋耗J(rèn)過(guò)濾器 → 當(dāng)前路由過(guò)濾器 → 全局過(guò)濾器。

六、Gateway跨域請(qǐng)求配置

1.跨域請(qǐng)求定義

跨域:請(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ì)被瀏覽器攔截。

2.跨域常見(jiàn)解決方案

使用CORS方式。

CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱(chēng)是"跨域資源共享"(Cross-origin resource sharing)。

它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。

3.跨域請(qǐng)求解決方案

方式一:配置application.yml文件:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域配置
        add-to-simple-url-handler-mapping: true # 解決options請(qǐng)求被攔截問(wèn)題
               # options請(qǐng)求 就是一種詢(xún)問(wèn)服務(wù)器是否瀏覽器可以跨域的請(qǐng)求
               # 如果每次跨域都有詢(xún)問(wèn)服務(wù)器是否瀏覽器可以跨域?qū)π阅芤彩菗p耗
               # 可以配置本次跨域檢測(cè)的有效期maxAge
               # 在maxAge設(shè)置的時(shí)間范圍內(nèi),不去詢(xún)問(wèn),統(tǒng)統(tǒng)允許跨域
        corsConfigurations:
          '[/**]':
            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ù)器壓力

方式二:使用編碼方式定義配置類(lèi):

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è)工具類(lèi)判斷當(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)求則放行
        };
    }
}

到此這篇關(guān)于springboot使用Gateway做網(wǎng)關(guān)并且配置全局?jǐn)r截器的文章就介紹到這了,更多相關(guān)springboot Gateway全局?jǐn)r截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

雷波县| 象山县| 嘉祥县| 扎赉特旗| 东明县| 龙山县| 桂平市| 正安县| 申扎县| 子洲县| 阿勒泰市| 绥德县| 绵阳市| 焦作市| 建德市| 托里县| 株洲县| 七台河市| 贡山| 安多县| 郧西县| 应用必备| 资源县| 山西省| 南皮县| 罗田县| 峨边| 禹州市| 龙陵县| 河津市| 龙海市| 江川县| 丹阳市| 鹤峰县| 富平县| 霍州市| 永新县| 清镇市| 新竹县| 威海市| 珠海市|