Java SpringBoot后端Filter包装请求(新增/覆盖请求头)

1.过滤器:TestFilter
java 复制代码
package com.visy.filter;

import cn.hutool.core.util.ObjectUtil;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class TestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String testValue = request.getHeader("Test-Key");

        if (ObjectUtil.isNull(testValue)) {
            // 创建可修改的请求包装器
            MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
            mutableRequest.addHeader("Test-Key", "hello");

            filterChain.doFilter(mutableRequest, response);
        } else {
            filterChain.doFilter(request, response);
        }
    }
}
2.请求包装器:MutableHttpServletRequest
java 复制代码
package com.visy.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.*;

public class MutableHttpServletRequest extends HttpServletRequestWrapper {
    private final Map<String, String> customHeaders;

    public MutableHttpServletRequest(HttpServletRequest request) {
        super(request);
        customHeaders = new HashMap<>();
    }

    public void addHeader(String name, String value) {
        this.customHeaders.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        String headerValue = customHeaders.get(name);
        if (headerValue != null) {
            return headerValue;
        }
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }

    // Tips: 一定要写,不然@RequestHeader单个值的时候获取不到参数
    @Override
    public Enumeration<String> getHeaders(String name){
        String value = getHeader(name);
        if (value != null) {
            return Collections.enumeration(Collections.singletonList(value));
        }
        return super.getHeaders(name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        Set<String> headerNames = new HashSet<>(customHeaders.keySet());
        Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
        while (e.hasMoreElements()) {
            headerNames.add(e.nextElement());
        }
        return Collections.enumeration(headerNames);
    }
}
3.测试
java 复制代码
@PostMapping({"/test"})
   public void test( @RequestHeader Map<String, String> headers, @RequestHeader("Test-Key") String testKey, HttpServletRequest servletRequest) {
      System.out.println("testKey1: " + headers.get("Test-Key") ); //hello
      System.out.println("testKey2: " + testKey ); //hello
      System.out.println("testKey3: " + servletRequest.getHeader("Test-Key")); //hello
   }
相关推荐
sheji34162 小时前
【开题答辩全过程】以 家庭教育资源网为例,包含答辩的问题和答案
java
百***78752 小时前
Grok-4.1与GPT-5.2深度对比:技术差异、适用场景及Python集成指南
java·python·gpt
Mr -老鬼2 小时前
Java VS Rust
java·开发语言·rust
北凉军2 小时前
java连接达梦数据库,用户名是其他库的名称无法指定库,所有mapper查询的都是以用户名相同的库内的表
java·开发语言·数据库
程序员张32 小时前
Mybatis条件判断某属性是否等于指定字符串
java·spring boot·mybatis
wuk9982 小时前
基于C#与三菱PLC通过TCPIP实现MC协议通信示例
java·网络·c#
沛沛老爹2 小时前
Web转AI架构篇 Agent Skills vs MCP:工具箱与标准接口的本质区别
java·开发语言·前端·人工智能·架构·企业开发
码农小卡拉3 小时前
Maven与Gradle选型指南:如何匹配项目的依赖管理需求
java·gradle·maven
黎雁·泠崖3 小时前
吃透Java操作符进阶:算术+移位操作符 全解析(Java&C区别+完整案例+避坑指南)
java·c语言·python