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

修改request請求的header請求頭實(shí)現(xiàn)方式

 更新時(shí)間:2026年04月28日 09:54:27   作者:我真的不吃辣條  
本文介紹了在Spring Cloud Gateway中修改HTTP請求頭的方法,包括直接操作ServerHttpRequest對(duì)象和創(chuàng)建自定義Request請求包裝類兩種方式,此方法可用于替換Authorization請求頭中的token

問題和場景

默認(rèn)http傳輸不能中途修改http內(nèi)容, 但是有很多時(shí)候都需要去修改請求頭信息來達(dá)到某些目的,比如我這個(gè)情況:

我需要去修改Authorization請求頭來替換token,我在網(wǎng)上看了好多博客都是HttpServletRequest類的或者是想用反射解決,但是我這里(ServerHttpRequest)并不適用,于是我去求助大佬后得出2個(gè)解決方案,并且ServerHttpRequest和HttpServletRequest都適用。

如果直接set值會(huì)有如下問題:

java.lang.UnsupportedOperationException:null;

at org.springframework.http.ReadOnlyHttpHeaders.set:

解決(ServerHttpRequest)

方案一 直接開放權(quán)限

這個(gè)方法主要是為了兼容以前的代碼,因?yàn)檫@個(gè)header到其他方法里面還會(huì)改 所以我改了header對(duì)象

 //設(shè)置為可修改的
headers= HttpHeaders.writableHttpHeaders(headers);
//設(shè)置請求頭
headers.set(HttpHeaders.AUTHORIZATION,authorization);

方案二 去修改header

這個(gè)是等于重新build對(duì)象 ,貌似更方便

exchange.getRequest().mutate().header(HttpHeaders.AUTHORIZATION,authorization).build();

上面2種方法都可以實(shí)現(xiàn)這個(gè)效果

修改請求前:

修改請求后:

完整代碼如下:

package org.dromara.soul.bootstrap.filter;

import com.alibaba.nacos.client.utils.StringUtils;
import org.dromara.soul.bootstrap.template.RedisStrTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
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.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.annotation.Nullable;

import javax.xml.soap.MimeHeaders;
import java.lang.reflect.Field;
import java.util.List;

/**
 * @Auther: whhh
 * @Date: 2021/4/1 10:46
 * @Description: token替換
 */

@Order(-98)
@Component
public class GetTokenFilter implements WebFilter {

    @Autowired
    private RedisStrTemplate redisStrTemplate;

    @Override
    public Mono<Void> filter(@Nullable final ServerWebExchange exchange, @Nullable final WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        //判斷是否包含認(rèn)證頭
        if (request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
            HttpHeaders headers = request.getHeaders();
            //獲取認(rèn)證集合
            List<String> keys = headers.get(HttpHeaders.AUTHORIZATION);
            if (keys != null) {
                //多個(gè)認(rèn)證取第一個(gè)不為空的
                for (String token : keys) {
                    if (token != null && !token.equals("")) {
                        //從Redis獲取token
                        String a = (String) redisStrTemplate.get(token);
                        String authorization = a.substring(1,a.length()-1);//
                        //方法一 設(shè)置為可修改的
                        headers= HttpHeaders.writableHttpHeaders(headers);
                        //設(shè)置請求頭
                        headers.set(HttpHeaders.AUTHORIZATION,authorization);



                        //方法二 bulid
//                        exchange.getRequest().mutate().header(HttpHeaders.AUTHORIZATION,authorization).build();

                        if (request.getMethod() == HttpMethod.OPTIONS) {
                            exchange.getResponse().setStatusCode(HttpStatus.OK);
                            return Mono.empty();
                        }

                    }

                }
            }
        }
        return chain.filter(exchange);
    }



}

PS:我這個(gè)filter是soul網(wǎng)關(guān)(shenyu)的哦,可能chain有區(qū)別,你可以參考直接創(chuàng)建一個(gè)filter

解決(HttpServletRequest)

你可以自定義個(gè)RemoteAddrFilter,然后通過覆蓋HttpServletRequestWrapper去替換原有的方法,基于HttpServletRequest 創(chuàng)建SafeboxRequestWrapper對(duì)象,然后把SafeboxRequestWrapper對(duì)象作為HttpServletRequest傳遞下去

代碼如下:

HeaderMapRequestWrapper類

package org.dromara.soul.bootstrap.filter;


import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;


/**
 * @Auther: whhh
 * @Date: 2021/4/26 19:00
 * @Description:
 */
public class HeaderMapRequestWrapper  extends HttpServletRequestWrapper{
    public HeaderMapRequestWrapper(HttpServletRequest request) {
        super(request);
    }


    private Map<String, String> headerMap = new HashMap<String, String>();

    /**
     * add a header with given name and value
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        headerMap.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        String headerValue = super.getHeader(name);
        if (headerMap.containsKey(name)) {
            headerValue = headerMap.get(name);
        }
        return headerValue;
    }

    /**
     * get the Header names
     */
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : headerMap.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> values = Collections.list(super.getHeaders(name));
        if (headerMap.containsKey(name)) {
            values.add(headerMap.get(name));
        }
        return Collections.enumeration(values);
    }
}

GetTokenFilter類

package org.dromara.soul.bootstrap.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


/**
 * @Auther: whhh
 * @Date: 2021/4/26 18:58
 * @Description:
 */
@Order(-98)
@Component
public class GetTokenFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req);
        //校驗(yàn)請求request Header中是否有對(duì)應(yīng)值
        String authorization = request.getParameter(HttpHeaders.AUTHORIZATION);
        if (language !=null && !"".equals(authorization)) {
            //如果get請求url中帶有這個(gè)參數(shù),則request中新增一個(gè)header
            requestWrapper.addHeader(HttpHeaders.AUTHORIZATION, authorization);
            // Goes to default servlet.
            chain.doFilter(requestWrapper, response);
        }
        // Goes to default servlet.
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 微信小程序訂閱消息推送實(shí)戰(zhàn)圖文教程(Java?Spring?Boot?+?Redis)

    微信小程序訂閱消息推送實(shí)戰(zhàn)圖文教程(Java?Spring?Boot?+?Redis)

    訂閱消息是微信小程序提供的一種消息推送方式,用戶可以訂閱某個(gè)公眾號(hào)或小程序的消息,當(dāng)有新消息時(shí),系統(tǒng)會(huì)自動(dòng)推送通知給用戶,這篇文章主要介紹了微信小程序訂閱消息推送(Java Spring Boot+Redis)的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • Java全面細(xì)致講解Cookie與Session及kaptcha驗(yàn)證碼的使用

    Java全面細(xì)致講解Cookie與Session及kaptcha驗(yàn)證碼的使用

    web開發(fā)階段我們主要是瀏覽器和服務(wù)器之間來進(jìn)行交互。瀏覽器和服務(wù)器之間的交互就像人和人之間進(jìn)行交流一樣,但是對(duì)于機(jī)器來說,在一次請求之間只是會(huì)攜帶著本次請求的數(shù)據(jù)的,但是可能多次請求之間是會(huì)有聯(lián)系的,所以提供了會(huì)話機(jī)制
    2022-06-06
  • SpringBoot結(jié)果封裝和異常攔截的實(shí)現(xiàn)示例

    SpringBoot結(jié)果封裝和異常攔截的實(shí)現(xiàn)示例

    SpringBoot 項(xiàng)目中,我們通常需要將結(jié)果數(shù)據(jù)封裝成特定的格式,以方便客戶端進(jìn)行處理,本文主要介紹了SpringBoot?優(yōu)雅的結(jié)果封裝和異常攔截,感興趣的可以了解一下
    2023-08-08
  • Java實(shí)現(xiàn)字符串匹配的示例代碼

    Java實(shí)現(xiàn)字符串匹配的示例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)字符串匹配,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Spring如何按業(yè)務(wù)模塊輸出日志到不同的文件詳解

    Spring如何按業(yè)務(wù)模塊輸出日志到不同的文件詳解

    最近做項(xiàng)目時(shí)有一個(gè)記錄操作日志的需求,比如某個(gè)用戶進(jìn)行了查詢、刪除、修改等操作,下面這篇文章主要給大家介紹了關(guān)于Spring如何按業(yè)務(wù)模塊輸出日志到不同文件的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • 幾種SpringBoot的屬性配置方式詳解

    幾種SpringBoot的屬性配置方式詳解

    通常項(xiàng)目配置信息都寫在.properties或者.yml文件中,但是打成jar包部署后,如果需要修改配置信息,還需要改完再重新打包部署,因此,下面介紹幾種SpringBoot的屬性配置方式,需要的朋友可以參考下
    2024-12-12
  • RabbitMQ使用SpringAMQP的配置方法

    RabbitMQ使用SpringAMQP的配置方法

    這篇文章主要介紹了RabbitMQ使用SpringAMQP的配置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • Spring Boot參數(shù)校驗(yàn)及分組校驗(yàn)的使用教程

    Spring Boot參數(shù)校驗(yàn)及分組校驗(yàn)的使用教程

    在日常的開發(fā)中,參數(shù)校驗(yàn)是非常重要的一個(gè)環(huán)節(jié),嚴(yán)格參數(shù)校驗(yàn)會(huì)減少很多出bug的概率,增加接口的安全性,下面這篇文章主要給大家介紹了關(guān)于Spring Boot參數(shù)校驗(yàn)及分組校驗(yàn)使用的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 基于SpringBoot+WebSocket實(shí)現(xiàn)網(wǎng)頁在線聊天室

    基于SpringBoot+WebSocket實(shí)現(xiàn)網(wǎng)頁在線聊天室

    文章介紹了從零構(gòu)建一套前后端分離的網(wǎng)頁聊天室系統(tǒng),涵蓋架構(gòu)設(shè)計(jì)、數(shù)據(jù)庫設(shè)計(jì)、登錄認(rèn)證、WebSocket實(shí)時(shí)消息推送及全局異常處理等核心功能,文章詳細(xì)描述了前端頁面與交互、后端技術(shù)棧及核心功能實(shí)現(xiàn)、數(shù)據(jù)庫設(shè)計(jì)等以及項(xiàng)目運(yùn)行等等內(nèi)容,需要的朋友可以參考下
    2026-05-05
  • MyBatis-Plus整合金倉數(shù)據(jù)庫KingbaseES的實(shí)戰(zhàn)指南

    MyBatis-Plus整合金倉數(shù)據(jù)庫KingbaseES的實(shí)戰(zhàn)指南

    隨著數(shù)字中國建設(shè)的深入推進(jìn),國產(chǎn)數(shù)據(jù)庫在關(guān)鍵業(yè)務(wù)系統(tǒng)中扮演著越來越重要的角色,本文將通過一個(gè)電商系統(tǒng)的實(shí)戰(zhàn)案例,深入探討MyBatis-Plus整合KingbaseES的詳細(xì)步驟吧
    2025-10-10

最新評(píng)論

河南省| 铜陵市| 永平县| 眉山市| 高陵县| 六枝特区| 宁城县| 鄯善县| 济源市| 县级市| 富源县| 资中县| 孝感市| 青神县| 固始县| 福鼎市| 冕宁县| 新郑市| 那曲县| 张家口市| 鹤峰县| 新丰县| 武威市| 开原市| 贵德县| 汽车| 麻江县| 宝应县| 潞城市| 拉萨市| 依安县| 广汉市| 伊金霍洛旗| 上高县| 梁河县| 朝阳市| 四川省| 迭部县| 信阳市| 左云县| 乌拉特中旗|