修改request请求的header请求头

问题和场景

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

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

目录(解决方案自己根据需求去查看,觉得有用点个赞哦)

问题和场景

解决(ServerHttpRequest)

方案一 直接开放权限

方案二 去修改header

解决(HttpServletRequest)

HeaderMapRequestWrapper类

GetTokenFilter类


如果直接set值会有如下问题,java.lang.UnsupportedOperationException:null;

                                                at org.springframework.http.ReadOnlyHttpHeaders.set:

image

解决(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() {
    }
}

  • 13
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值