当前位置: 代码网 > it编程>编程语言>Java > 修改request请求的header请求头实现方式

修改request请求的header请求头实现方式

2026年04月28日 Java 我要评论
问题和场景默认http传输不能中途修改http内容, 但是有很多时候都需要去修改请求头信息来达到某些目的,比如我这个情况:我需要去修改authorization请求头来替换token,我在网上看了好多

问题和场景

默认http传输不能中途修改http内容, 但是有很多时候都需要去修改请求头信息来达到某些目的,比如我这个情况:

我需要去修改authorization请求头来替换token,我在网上看了好多博客都是httpservletrequest类的或者是想用反射解决,但是我这里(serverhttprequest)并不适用,于是我去求助大佬后得出2个解决方案,并且serverhttprequest和httpservletrequest都适用。

如果直接set值会有如下问题:

java.lang.unsupportedoperationexception:null;

at org.springframework.http.readonlyhttpheaders.set:

解决(serverhttprequest)

方案一 直接开放权限

这个方法主要是为了兼容以前的代码,因为这个header到其他方法里面还会改 所以我改了header对象

 //设置为可修改的
headers= httpheaders.writablehttpheaders(headers);
//设置请求头
headers.set(httpheaders.authorization,authorization);

方案二 去修改header

这个是等于重新build对象 ,貌似更方便

exchange.getrequest().mutate().header(httpheaders.authorization,authorization).build();

上面2种方法都可以实现这个效果

修改请求前:

修改请求后:

完整代码如下:

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();
        //判断是否包含认证头
        if (request.getheaders().containskey(httpheaders.authorization)) {
            httpheaders headers = request.getheaders();
            //获取认证集合
            list<string> keys = headers.get(httpheaders.authorization);
            if (keys != null) {
                //多个认证取第一个不为空的
                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);//
                        //方法一 设置为可修改的
                        headers= httpheaders.writablehttpheaders(headers);
                        //设置请求头
                        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:我这个filter是soul网关(shenyu)的哦,可能chain有区别,你可以参考直接创建一个filter

解决(httpservletrequest)

你可以自定义个remoteaddrfilter,然后通过覆盖httpservletrequestwrapper去替换原有的方法,基于httpservletrequest 创建safeboxrequestwrapper对象,然后把safeboxrequestwrapper对象作为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);
        //校验请求request header中是否有对应值
        string authorization = request.getparameter(httpheaders.authorization);
        if (language !=null && !"".equals(authorization)) {
            //如果get请求url中带有这个参数,则request中新增一个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() {
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com