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

SpringCloudGateway網(wǎng)關(guān)處攔截并修改請求的操作方法

 更新時間:2023年12月23日 10:04:40   作者:風(fēng) 離  
這篇文章主要介紹了SpringCloudGateway網(wǎng)關(guān)處攔截并修改請求的操作方法,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

SpringCloudGateway網(wǎng)關(guān)處攔截并修改請求

需求背景

老系統(tǒng)沒有引入Token的概念,之前的租戶Id拼接在請求上,有的是以Get,Param傳參形式;有的是以Post,Body傳參的。需要在網(wǎng)關(guān)層攔截請求并進行請求修改后轉(zhuǎn)發(fā)到對應(yīng)服務(wù)。

舉個例子:

Get請求:

/user/getInfo?userId=1 經(jīng)過網(wǎng)關(guān)處理后變?yōu)?/user/getInfo?userId=1&&tenantId=2333

Post請求:

/user/getInfo Body攜帶參數(shù)為:

{
  userId: "1"
}

經(jīng)過網(wǎng)關(guān)處理后變?yōu)?/p>

{
  userId: "1",
  tenantId: "2333"
}

解決辦法

  • 全局過濾器配置: 通過@Bean注解配置一個全局過濾器,用于在請求被轉(zhuǎn)發(fā)到微服務(wù)前進行處理。
  • 處理GET請求: 如果是GET請求,直接修改URL并返回,不對請求體進行修改。
  • 處理非GET請求: 對非GET請求,使用裝飾者模式創(chuàng)建ModifyRequestBodyServerHttpRequestDecorator對象,對請求體進行修改。
  • 去掉Content-Length頭: 在修改請求體的同時,通過mutate()方法去掉請求頭中的Content-Length。
  • 修改請求體的裝飾者類: 定義了一個內(nèi)部類ModifyRequestBodyServerHttpRequestDecorator,繼承自ServerHttpRequestDecorator,用于實現(xiàn)請求體的修改。

代碼示例:

// 導(dǎo)入必要的類和包
package com.***.gateway.config;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Configuration
@Slf4j
public class GatewayConfig {
    // 配置全局過濾器
    @Bean
    public GlobalFilter customGlobalFilter() {
        return (exchange, chain) -> {
            // 獲取原始請求對象
            ServerHttpRequest request = exchange.getRequest();
            // 構(gòu)建URI組件構(gòu)建器,用于修改請求URL
            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUri(request.getURI());
            // 初始化租戶ID
            String tenantId = "";
            // 檢查請求頭中是否包含 "TenantId",如果有則獲取其值
            if (request.getHeaders().containsKey("TenantId")) {
                tenantId = request.getHeaders().get("TenantId").get(0);
                uriBuilder.queryParam("tenantId", tenantId);
            }
            // 如果請求是GET請求,則直接返回
            if (request.getMethodValue().equals("GET")) {
                log.info("請求是Get請求,url is {}", uriBuilder.build().toUri());
                ServerHttpRequest modifiedRequest = request.mutate().uri(uriBuilder.build().toUri()).build();
                // 創(chuàng)建新的ServerWebExchange,該對象包含修改后的請求
                ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();
                // 繼續(xù)執(zhí)行過濾器鏈
                return chain.filter(modifiedExchange);
            }
            // 使用裝飾者模式修改請求體
            ServerHttpRequest modifiedRequest = new ModifyRequestBodyServerHttpRequestDecorator(request, tenantId, exchange.getResponse().bufferFactory());
            // 去掉Content-Length請求頭
            modifiedRequest = modifiedRequest.mutate().header("Content-Length", (String) null).build();
            // 創(chuàng)建新的ServerWebExchange,該對象包含修改后的請求
            ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();
            // 繼續(xù)執(zhí)行過濾器鏈
            return chain.filter(modifiedExchange);
        };
    }
    // 定義修改請求體的裝飾者類
    private static class ModifyRequestBodyServerHttpRequestDecorator extends ServerHttpRequestDecorator {
        private final String tenantId;
        private final DataBufferFactory bufferFactory;
        private final ObjectMapper objectMapper = new ObjectMapper();
        // 構(gòu)造方法,傳入原始請求、tenantId和數(shù)據(jù)緩沖工廠
        ModifyRequestBodyServerHttpRequestDecorator(ServerHttpRequest delegate, String tenantId, DataBufferFactory bufferFactory) {
            super(delegate);
            this.tenantId = tenantId;
            this.bufferFactory = bufferFactory;
        }
        // 重寫獲取請求體的方法,對請求體進行修改
        @NotNull
        @Override
        public Flux<DataBuffer> getBody() {
            return super.getBody().map(dataBuffer -> {
                // 讀取原始請求體數(shù)據(jù)
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                String body = new String(bytes, StandardCharsets.UTF_8);
                // 修改請求體內(nèi)容
                String newBody = modifyJsonBody(body);
                // 創(chuàng)建新的 DataBuffer
                byte[] newData = newBody.getBytes(StandardCharsets.UTF_8);
                return bufferFactory.wrap(newData);
            });
        }
        // 對 JSON 請求體進行修改,添加 tenantId 字段
        private String modifyJsonBody(String originalBody) {
            try {
                JsonNode jsonNode = objectMapper.readTree(originalBody);
                ((ObjectNode) jsonNode).put("tenantId", tenantId);
                return objectMapper.writeValueAsString(jsonNode);
            } catch (IOException e) {
                log.error("Error modifying JSON body", e);
                return originalBody;
            }
        }
    }
}

解決路徑文章參考

http://t.csdnimg.cn/9kos5

http://t.csdnimg.cn/Aklwh

關(guān)于裝飾者模式

裝飾者模式是一種結(jié)構(gòu)型設(shè)計模式,它允許你通過將對象放入包含行為的特殊封裝類中來為原始對象添加新的行為。這種模式能夠在不修改原始對象的情況下,動態(tài)地擴展其功能。在上段代碼里,主要使用裝飾者模式去修改Body 的傳參。

主要角色:

  • Component(組件): 定義一個抽象接口或抽象類,聲明對象的一些基本操作。
  • ConcreteComponent(具體組件): 實現(xiàn)了Component接口,是被裝飾的具體對象,也是我們最終要添加新行為的對象。
  • Decorator(裝飾者抽象類): 繼承了Component,并持有一個Component對象的引用,同時實現(xiàn)了Component定義的接口。它可以通過該引用調(diào)用Component的操作,同時可以添加、擴展或修改Component的行為。
  • ConcreteDecorator(具體裝飾者): 擴展Decorator,具體實現(xiàn)新行為的類。

裝飾者模式的工作流程:

  • 客戶端通過Component接口與ConcreteComponent對象進行交互。
  • ConcreteComponent對象處理客戶端的請求。
  • 客戶端可以通過Decorator接口與ConcreteDecorator對象進行交互,Decorator持有ConcreteComponent的引用。
  • ConcreteDecorator在調(diào)用ConcreteComponent的操作前后,可以添加、擴展或修改行為。

給普通咖啡加點糖和牛奶

代碼示例:

public class DecoratorPatternExample {
    // Component(組件)
    interface Coffee {
        String getDescription();
        double cost();
    }
    // ConcreteComponent(具體組件)
    static class SimpleCoffee implements Coffee {
        @Override
        public String getDescription() {
            return "Simple Coffee";
        }
        @Override
        public double cost() {
            return 1.0;
        }
    }
    // Decorator(裝飾者抽象類)
    abstract static class CoffeeDecorator implements Coffee {
        protected Coffee decoratedCoffee;
        public CoffeeDecorator(Coffee coffee) {
            this.decoratedCoffee = coffee;
        }
        @Override
        public String getDescription() {
            return decoratedCoffee.getDescription();
        }
        @Override
        public double cost() {
            return decoratedCoffee.cost();
        }
    }
    // ConcreteDecorator(具體裝飾者)
    static class MilkDecorator extends CoffeeDecorator {
        public MilkDecorator(Coffee coffee) {
            super(coffee);
        }
        @Override
        public String getDescription() {
            return super.getDescription() + ", with Milk";
        }
        @Override
        public double cost() {
            return super.cost() + 0.5;
        }
    }
    // ConcreteDecorator(具體裝飾者)
    static class SugarDecorator extends CoffeeDecorator {
        public SugarDecorator(Coffee coffee) {
            super(coffee);
        }
        @Override
        public String getDescription() {
            return super.getDescription() + ", with Sugar";
        }
        @Override
        public double cost() {
            return super.cost() + 0.2;
        }
    }
    public static void main(String[] args) {
        // 創(chuàng)建一個簡單的咖啡
        Coffee simpleCoffee = new SimpleCoffee();
        System.out.println("Cost: " + simpleCoffee.cost() + ", Description: " + simpleCoffee.getDescription());
        // 使用裝飾者模式添加牛奶和糖
        Coffee milkSugarCoffee = new MilkDecorator(new SugarDecorator(simpleCoffee));
        System.out.println("Cost: " + milkSugarCoffee.cost() + ", Description: " + milkSugarCoffee.getDescription());
    }
}

到此這篇關(guān)于SpringCloudGateway網(wǎng)關(guān)處攔截并修改請求的文章就介紹到這了,更多相關(guān)SpringCloud Gateway網(wǎng)關(guān)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA 泛型與通配符詳解從原理到實戰(zhàn)應(yīng)用

    JAVA 泛型與通配符詳解從原理到實戰(zhàn)應(yīng)用

    本章全面介紹了泛型的核心概念、設(shè)計初衷及三大使用方式(泛型類、泛型接口、泛型方法),重點講解了泛型的擦除機制和通配符的靈活運用,強調(diào)了泛型在編譯期類型安全和運行時類型擦除的優(yōu)勢,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • RocketMQ?producer容錯機制源碼解析

    RocketMQ?producer容錯機制源碼解析

    這篇文章主要為大家介紹了RocketMQ?producer容錯機制源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Java線程之join_動力節(jié)點Java學(xué)院整理

    Java線程之join_動力節(jié)點Java學(xué)院整理

    join() 定義在Thread.java中,下文通過源碼分享join(),需要的朋友參考下吧
    2017-05-05
  • Java抽象類、繼承及多態(tài)和適配器的實現(xiàn)代碼

    Java抽象類、繼承及多態(tài)和適配器的實現(xiàn)代碼

    這篇文章主要介紹了Java抽象類、繼承及多態(tài)和適配器的實現(xiàn),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-06-06
  • IDEA連接mysql保姆級教學(xué)教程

    IDEA連接mysql保姆級教學(xué)教程

    學(xué)習(xí)使用IDEA的時候,需要連接Database,下面這篇文章主要給大家介紹了關(guān)于IDEA連接mysql的保姆級教學(xué)教程,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • SpringBoot下無節(jié)制和數(shù)據(jù)庫建立連接的問題及解決方法

    SpringBoot下無節(jié)制和數(shù)據(jù)庫建立連接的問題及解決方法

    本文介紹了無節(jié)制建立MySQL連接的危害,包括數(shù)據(jù)庫服務(wù)端資源耗盡、應(yīng)用端性能劣化和監(jiān)控與運維困境,提出了系統(tǒng)性解決方案,包括連接池標準化配置、代碼規(guī)范與防御式編程、全鏈路監(jiān)控體系和架構(gòu)級優(yōu)化,感興趣的朋友一起看看吧
    2025-03-03
  • Java輕松實現(xiàn)Excel轉(zhuǎn)PDF的實戰(zhàn)指南

    Java輕松實現(xiàn)Excel轉(zhuǎn)PDF的實戰(zhàn)指南

    這篇文章主要介紹了兩種將Excel轉(zhuǎn)換為PDF的方法,第一種使用Spire.XLS免費版,第二種方法(破解版)支持多頁轉(zhuǎn)換,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2026-03-03
  • @Transactional注解不起作用的原因分析及解決

    @Transactional注解不起作用的原因分析及解決

    這篇文章主要介紹了@Transactional注解不起作用的原因分析及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • maven?scope?provided和runtime的例子說明

    maven?scope?provided和runtime的例子說明

    這篇文章主要介紹了maven?scope?provided和runtime的例子說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Spring攔截器和過濾器的區(qū)別在哪?

    Spring攔截器和過濾器的區(qū)別在哪?

    相信很多小伙伴都對Spring攔截器和過濾器的區(qū)別有疑惑,今天特地整理了本篇文章,文中有非常詳細的介紹,需要的朋友可以參考下
    2021-06-06

最新評論

澄迈县| 新营市| 门源| 丹江口市| 顺义区| 唐河县| 十堰市| 平凉市| 图木舒克市| 马边| 泽普县| 额济纳旗| 常德市| 吉木乃县| 夹江县| 林口县| 乌兰县| 寻乌县| 永新县| 琼结县| 淮北市| 静宁县| 福贡县| 娱乐| 吉隆县| 盐山县| 商都县| 连山| 榆树市| 宁明县| 盐边县| 麦盖提县| 突泉县| 湄潭县| 景泰县| 武邑县| 洪洞县| 平陆县| 玉龙| 桐柏县| 棋牌|