欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例

 更新時(shí)間:2021年12月13日 08:30:07   作者:程序員欣宸  
本文主要介紹了Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

這里分類(lèi)和匯總了欣宸的全部原創(chuàng)(含配套源碼):https://github.com/zq2599/blog_demos

本篇概覽

作為《Spring Cloud Gateway實(shí)戰(zhàn)》系列的第十四篇,本文會(huì)繼續(xù)發(fā)掘Spring Cloud Gateway的潛力,通過(guò)編碼體驗(yàn)操控網(wǎng)關(guān)的樂(lè)趣,開(kāi)發(fā)出一個(gè)實(shí)用的功能:讓Spring Cloud Gateway應(yīng)用在收到請(qǐng)求后,可以按照業(yè)務(wù)的需要跳轉(zhuǎn)到任意的地址去

一般路由規(guī)則

先來(lái)看一個(gè)普通的路由規(guī)則,如下所示,意思是將所有/hello/**的請(qǐng)求轉(zhuǎn)發(fā)到http://127.0.0.1:8082這個(gè)地址去:

spring:
  application:
    name: hello-gateway
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**

上述規(guī)則的功能如下圖所示,假設(shè)這就是生產(chǎn)環(huán)境的樣子,192.168.50.99:8082是提供服務(wù)的后臺(tái)應(yīng)用:

在這里插入圖片描述?

特殊規(guī)則

以上是常規(guī)情況,但也有些特殊情況,要求SpringCloud Gateway把瀏覽器的請(qǐng)求轉(zhuǎn)發(fā)到不同的服務(wù)上去

如下圖所示,在之前的環(huán)境中增加了另一個(gè)服務(wù)(即藍(lán)色塊),假設(shè)藍(lán)色服務(wù)代表測(cè)試環(huán)境

在這里插入圖片描述

瀏覽器發(fā)起的/hello/str請(qǐng)求中,如果header中帶有tag-test-user,并且值等于true,此時(shí)要求SpringCloud Gateway把這個(gè)請(qǐng)求轉(zhuǎn)發(fā)到測(cè)試環(huán)境

如果瀏覽器的請(qǐng)求header中沒(méi)有tag-test-user,SpringCloud Gateway需要像以前那樣繼續(xù)轉(zhuǎn)發(fā)到192.168.50.99:8082

很明顯,上述需求難以通過(guò)配置來(lái)實(shí)現(xiàn),因?yàn)檗D(zhuǎn)發(fā)的地址和轉(zhuǎn)發(fā)邏輯都是圍繞業(yè)務(wù)邏輯來(lái)定制的,這也就是本篇的目標(biāo):對(duì)同一個(gè)請(qǐng)求path,可以通過(guò)編碼轉(zhuǎn)發(fā)到不同的地方去

實(shí)現(xiàn)上述功能的具體做法是:自定義過(guò)濾器

設(shè)計(jì)

  • 編碼之前先設(shè)計(jì),把關(guān)鍵點(diǎn)想清楚再動(dòng)手
  • 今天咱們要開(kāi)發(fā)一個(gè)SpringCloud Gateway應(yīng)用,里面新增一個(gè)自定義過(guò)濾器
  • 實(shí)現(xiàn)這個(gè)功能需要三個(gè)知識(shí)點(diǎn)作為基礎(chǔ),也就是說(shuō),您會(huì)通過(guò)本篇實(shí)戰(zhàn)掌握以下知識(shí)點(diǎn):
    • 自定義過(guò)濾器
    • 自定義過(guò)濾器的配置參數(shù)和bean的映射
    • 編碼構(gòu)造Route實(shí)例

用思維導(dǎo)圖將具體工作內(nèi)容展開(kāi),如下圖所示,咱們就按部就班的實(shí)現(xiàn)吧:

在這里插入圖片描述?

源碼下載

本篇實(shí)戰(zhàn)中的完整源碼可在GitHub下載到,地址和鏈接信息如下表所示(https://github.com/zq2599/blog_demos):

名稱 鏈接 備注
項(xiàng)目主頁(yè) https://github.com/zq2599/blog_demos 該項(xiàng)目在GitHub上的主頁(yè)
git倉(cāng)庫(kù)地址(https) https://github.com/zq2599/blog_demos.git 該項(xiàng)目源碼的倉(cāng)庫(kù)地址,https協(xié)議
git倉(cāng)庫(kù)地址(ssh) git@github.com:zq2599/blog_demos.git 該項(xiàng)目源碼的倉(cāng)庫(kù)地址,ssh協(xié)議

這個(gè)git項(xiàng)目中有多個(gè)文件夾,本篇的源碼在spring-cloud-tutorials文件夾下,如下圖紅框所示:

spring-cloud-tutorials內(nèi)部有多個(gè)子項(xiàng)目,本篇的源碼在gateway-dynamic-route文件夾下,如下圖紅框所示:

在這里插入圖片描述?

編碼

新建名為gateway-dynamic-route的maven工程,其pom.xml內(nèi)容如下:

<?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-tutorials</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway-dynamic-route</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 如果父工程不是springboot,就要用以下方式使用插件,才能生成正常的jar -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.bolingcavalry.gateway.GatewayDynamicRouteApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

啟動(dòng)類(lèi)是普通的SpringBoot啟動(dòng)類(lèi):

package com.bolingcavalry.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

接下來(lái)是本篇的核心,自定義過(guò)濾器類(lèi),代碼中已經(jīng)添加了詳細(xì)的注釋,有幾處要注意的地方稍后會(huì)提到:

上述代碼中要注意的地方如下:

BizLogicRouteConfig是過(guò)濾器的配置類(lèi),可以在使用過(guò)濾器時(shí)在配置文件中配置prodEnvUri和testEnvUri的值,在代碼中可以通過(guò)這兩個(gè)字段取得配置值

過(guò)濾器的工廠類(lèi)名為BizLogicRouteGatewayFilterFactory,按照規(guī)則,過(guò)濾器的名字是BizLogicRoute

package com.bolingcavalry.gateway.filter;

import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;

@Component
@Slf4j
public class BizLogicRouteGatewayFilterFactory extends AbstractGatewayFilterFactory<BizLogicRouteGatewayFilterFactory.BizLogicRouteConfig> {

    private static final String TAG_TEST_USER = "tag-test-user";

    public BizLogicRouteGatewayFilterFactory() {
        super(BizLogicRouteConfig.class);
    }

    @Override
    public GatewayFilter apply(BizLogicRouteConfig config) {

        return (exchange, chain) -> {
            // 本次的請(qǐng)求對(duì)象
            ServerHttpRequest request =  exchange.getRequest();

            // 調(diào)用方請(qǐng)求時(shí)的path
            String rawPath = request.getURI().getRawPath();

            log.info("rawPath [{}]", rawPath);

            // 請(qǐng)求頭
            HttpHeaders headers = request.getHeaders();

            // 請(qǐng)求方法
            HttpMethod httpMethod = request.getMethod();

            // 請(qǐng)求參數(shù)
            MultiValueMap<String, String> queryParams = request.getQueryParams();

            // 這就是定制的業(yè)務(wù)邏輯,isTestUser等于ture代表當(dāng)前請(qǐng)求來(lái)自測(cè)試用戶,需要被轉(zhuǎn)發(fā)到測(cè)試環(huán)境
            boolean isTestUser = false;

            // 如果header中有tag-test-user這個(gè)key,并且值等于true(不區(qū)分大小寫(xiě)),
            // 就認(rèn)為當(dāng)前請(qǐng)求是測(cè)試用戶發(fā)來(lái)的
            if (headers.containsKey(TAG_TEST_USER)) {
                String tageTestUser = headers.get(TAG_TEST_USER).get(0);

                if ("true".equalsIgnoreCase(tageTestUser)) {
                    isTestUser = true;
                }
            }

            URI uri;

            if (isTestUser) {
                log.info("這是測(cè)試用戶的請(qǐng)求");
                // 從配置文件中得到測(cè)試環(huán)境的uri
                uri = UriComponentsBuilder.fromHttpUrl(config.getTestEnvUri() + rawPath).queryParams(queryParams).build().toUri();
            } else {
                log.info("這是普通用戶的請(qǐng)求");
                // 從配置文件中得到正式環(huán)境的uri
                uri = UriComponentsBuilder.fromHttpUrl(config.getProdEnvUri() + rawPath).queryParams(queryParams).build().toUri();
            }

            // 生成新的Request對(duì)象,該對(duì)象放棄了常規(guī)路由配置中的spring.cloud.gateway.routes.uri字段
            ServerHttpRequest serverHttpRequest = request.mutate().uri(uri).method(httpMethod).headers(httpHeaders -> httpHeaders = httpHeaders).build();

            // 取出當(dāng)前的route對(duì)象
            Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
            //從新設(shè)置Route地址
            Route newRoute =
                    Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId())
                            .order(route.getOrder()).uri(uri).build();
            // 放回exchange中
            exchange.getAttributes().put(GATEWAY_ROUTE_ATTR,newRoute);

            // 鏈?zhǔn)教幚?,交給下一個(gè)過(guò)濾器
            return chain.filter(exchange.mutate().request(serverHttpRequest).build());
        };
    }

    /**
     * 這是過(guò)濾器的配置類(lèi),配置信息會(huì)保存在此處
     */
    @Data
    @ToString
    public static class BizLogicRouteConfig {
        // 生產(chǎn)環(huán)境的服務(wù)地址
        private String prodEnvUri;

        // 測(cè)試環(huán)境的服務(wù)地址
        private String testEnvUri;
    }
}

在apply方法中,重新創(chuàng)建ServerHttpRequest和Route對(duì)象,它們的參數(shù)可以按照業(yè)務(wù)需求隨意設(shè)置,然后再將這兩個(gè)對(duì)象設(shè)置給SpringCloud gateway的處理鏈中,接下來(lái),處理鏈上的其他過(guò)濾拿到的就是新的ServerHttpRequest和Route對(duì)象了

配置

假設(shè)生產(chǎn)環(huán)境地址是http://127.0.0.1:8082,測(cè)試環(huán)境地址是http://127.0.0.1:8087,整個(gè)SpringCloud Gateway應(yīng)用的配置文件如下,可見(jiàn)使用了剛剛創(chuàng)建的過(guò)濾器,并且為此過(guò)濾器配置了兩個(gè)參數(shù):

server:
  #服務(wù)端口
  port: 8086
spring:
  application:
    name: gateway-dynamic-route
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://0.0.0.0:8082
          predicates:
          - Path=/hello/**
          filters:
            - name: BizLogicRoute
              args:
                prodEnvUri: http://127.0.0.1:8082
                testEnvUri: http://127.0.0.1:8087

至此,編碼完成了,啟動(dòng)這個(gè)服務(wù)

開(kāi)發(fā)和啟動(dòng)后臺(tái)服務(wù),模擬生產(chǎn)和測(cè)試環(huán)境

接下來(lái)開(kāi)始驗(yàn)證功能是否生效,咱們要準(zhǔn)備兩個(gè)后臺(tái)服務(wù):

模擬生產(chǎn)環(huán)境的后臺(tái)服務(wù)是provider-hello,監(jiān)聽(tīng)端口是8082,其/hello/str接口的返回值是Hello World, 2021-12-12 10:53:09

模擬測(cè)試環(huán)境的后臺(tái)服務(wù)是provider-for-test-user,監(jiān)聽(tīng)端口是8087,其/hello/str接口的返回值是Hello World, 2021-12-12 10:57:11 (from test enviroment)(和生產(chǎn)環(huán)境相比,返回內(nèi)容多了個(gè)(from test enviroment)),對(duì)應(yīng)Controller參考如下:

package com.bolingcavalry.provider.controller;

import com.bolingcavalry.common.Constants;
import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@RestController
@RequestMapping("/hello")
public class Hello {

    private String dateStr(){
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    }

    /**
     * 返回字符串類(lèi)型
     * @return
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.HELLO_PREFIX + ", " + dateStr() + " (from test enviroment)";
    }
}

以上兩個(gè)服務(wù),對(duì)應(yīng)的代碼都在我的Github倉(cāng)庫(kù)中,如下圖紅框所示:

在這里插入圖片描述

啟動(dòng)gateway-dynamic-route、provider-hello、provider-for-test-user服務(wù)

此時(shí),SpringCloud gateway應(yīng)用和兩個(gè)后臺(tái)服務(wù)都啟動(dòng)完成,情況如下圖,接下來(lái)驗(yàn)證剛才開(kāi)發(fā)的過(guò)濾器能不能像預(yù)期那樣轉(zhuǎn)發(fā):

在這里插入圖片描述?

驗(yàn)證

用postman工具向gateway-dynamic-route應(yīng)用發(fā)起一次請(qǐng)求,返回值如下圖紅框所示,證明這是provider-hello的響應(yīng),看來(lái)咱們的請(qǐng)求已經(jīng)正常到達(dá):

在這里插入圖片描述

再發(fā)送一次請(qǐng)求,如下圖,這次在header中加入鍵值對(duì),得到的結(jié)果是provider-for-test-user的響應(yīng)

在這里插入圖片描述

至此,過(guò)濾器的開(kāi)發(fā)和驗(yàn)證已經(jīng)完成,通過(guò)編碼,可以把外部請(qǐng)求轉(zhuǎn)發(fā)到任何咱們需要的地址去,并且支持參數(shù)配置,這個(gè)過(guò)濾器還有一定的可配置下,減少了硬編碼的比率,如果您正在琢磨如何深度操控SpringCloud Gateway,希望本文能給您一些參考

到此這篇關(guān)于Spring Cloud Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例的文章就介紹到這了,更多相關(guān)Spring Cloud Gateway 任意地址跳轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用idea生成webservice客戶端超詳解步驟(wsdl文件的使用)

    利用idea生成webservice客戶端超詳解步驟(wsdl文件的使用)

    這篇文章主要給大家介紹了關(guān)于利用idea生成webservice客戶端超詳解步驟,第一次接觸webservice,從采坑到采坑,算是了解了一些,明白了一些,文中通過(guò)代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • Java 深拷貝與淺拷貝的分析

    Java 深拷貝與淺拷貝的分析

    本文主要介紹java 的深拷貝和淺拷貝,這里通過(guò)實(shí)例代碼對(duì)深拷貝和淺拷貝做了詳細(xì)的比較,希望能幫到有需要的小伙伴
    2016-07-07
  • Java正則表達(dá)式驗(yàn)證固定電話號(hào)碼符合性

    Java正則表達(dá)式驗(yàn)證固定電話號(hào)碼符合性

    這篇文章主要介紹了Java正則表達(dá)式驗(yàn)證固定電話號(hào)碼符合性的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • java操作mysql實(shí)現(xiàn)增刪改查的方法

    java操作mysql實(shí)現(xiàn)增刪改查的方法

    這篇文章主要介紹了java操作mysql實(shí)現(xiàn)增刪改查的方法,結(jié)合實(shí)例形式分析了java操作mysql數(shù)據(jù)庫(kù)進(jìn)行增刪改查的具體實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • 使用監(jiān)聽(tīng)器對(duì)Spring bean id進(jìn)行唯一校驗(yàn)過(guò)程解析

    使用監(jiān)聽(tīng)器對(duì)Spring bean id進(jìn)行唯一校驗(yàn)過(guò)程解析

    這篇文章主要介紹了使用監(jiān)聽(tīng)器對(duì)Spring bean id進(jìn)行唯一校驗(yàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 關(guān)于在IDEA熱部署插件JRebel使用問(wèn)題詳解

    關(guān)于在IDEA熱部署插件JRebel使用問(wèn)題詳解

    這篇文章主要介紹了關(guān)于在IDEA熱部署插件JRebel使用問(wèn)題詳解,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Spring Batch讀取txt文件并寫(xiě)入數(shù)據(jù)庫(kù)的方法教程

    Spring Batch讀取txt文件并寫(xiě)入數(shù)據(jù)庫(kù)的方法教程

    這篇文章主要給大家介紹了Spring Batch讀取txt文件并寫(xiě)入數(shù)據(jù)庫(kù)的方法,SpringBatch 是一個(gè)輕量級(jí)、全面的批處理框架。這里我們用它來(lái)實(shí)現(xiàn)文件的讀取并將讀取的結(jié)果作處理,處理之后再寫(xiě)入數(shù)據(jù)庫(kù)中的功能。需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-04-04
  • 一文解讀java.nio.ByteBuffer

    一文解讀java.nio.ByteBuffer

    這篇文章主要介紹了java.nio.ByteBuffer的用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 三行Java代碼實(shí)現(xiàn)計(jì)算多邊形的幾何中心點(diǎn)

    三行Java代碼實(shí)現(xiàn)計(jì)算多邊形的幾何中心點(diǎn)

    因?yàn)楣ぷ餍枰?jì)算采煤機(jī)工作面的中心點(diǎn),如果套用數(shù)學(xué)的計(jì)算公式,用java去實(shí)現(xiàn),太麻煩了。本文將利用java幾何計(jì)算的工具包,幾行代碼就能求出多變形的中心,簡(jiǎn)直yyds!還不快跟隨小編一起學(xué)起來(lái)
    2022-10-10
  • springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問(wèn)題及解決

    springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問(wèn)題及解決

    這篇文章主要介紹了springboot使用alibaba的druid數(shù)據(jù)庫(kù)連接池錯(cuò)誤的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論