You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在请求抵达Controller前通过Filter修改请求头?

问题描述

无法在Filter(当作拦截器使用)中修改请求头,希望在请求到达Controller前修改已存在的请求头。

当前Filter实现代码:

public class MyInterceptor implements Filter {
   

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        //something
        //myHeaders is still present when send a request
        req.setAttribute("myHeaders","someValue");
        chain.doFilter(req, res);
    }
}

期望在Controller中获取修改后的请求头,Controller代码:

@RestController
@RequestMapping("/")
public class FooClass{
    
        @Autowired
        private Service service;

        @GetMapping("/foo")
        public ResponseEntity<Void> fooApi(
                @RequestHeader(value = "myHeaders") String myHeaders,
        ) {
            service.doSomething(myHeaders);
            return ResponseEntity.ok().build();
        }
}

解决方案

原生HttpServletRequest的请求头是不可修改的,必须通过请求包装类改写头信息的获取逻辑,具体操作如下:

  • 自定义HttpServletRequestWrapper子类,重写请求头相关方法,实现修改逻辑:
public class ModifiedHeaderRequestWrapper extends HttpServletRequestWrapper {
    private final Map<String, String> modifiedHeaders;

    public ModifiedHeaderRequestWrapper(HttpServletRequest request, Map<String, String> modifiedHeaders) {
        super(request);
        this.modifiedHeaders = new HashMap<>(modifiedHeaders);
    }

    @Override
    public String getHeader(String name) {
        // 优先返回修改后的头值,没有则使用原生请求的头
        if (modifiedHeaders.containsKey(name)) {
            return modifiedHeaders.get(name);
        }
        return super.getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> values = new ArrayList<>();
        if (modifiedHeaders.containsKey(name)) {
            values.add(modifiedHeaders.get(name));
        }
        // 合并原生请求的同名头值(若不需要保留原数值,可删除这段逻辑)
        Enumeration<String> originalHeaders = super.getHeaders(name);
        while (originalHeaders.hasMoreElements()) {
            values.add(originalHeaders.nextElement());
        }
        return Collections.enumeration(values);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        Set<String> headerNames = new HashSet<>(Collections.list(super.getHeaderNames()));
        headerNames.addAll(modifiedHeaders.keySet());
        return Collections.enumeration(headerNames);
    }
}
  • 修改Filter代码,使用包装后的请求对象传递给后续调用链:
public class MyInterceptor implements Filter {
   

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;

        // 定义需要修改的请求头键值对
        Map<String, String> headersToModify = new HashMap<>();
        headersToModify.put("myHeaders", "someValue");

        // 包装原生请求
        ModifiedHeaderRequestWrapper wrappedRequest = new ModifiedHeaderRequestWrapper(req, headersToModify);

        // 传递包装后的请求到后续链
        chain.doFilter(wrappedRequest, res);
    }
}
  • 确保Filter已在Spring容器中正确注册(可通过@WebFilter注解配合@ServletComponentScan,或者通过配置类手动注册),保证请求会经过该Filter处理。

完成以上操作后,请求到达Controller时,@RequestHeader("myHeaders")就能获取到你修改后的数值。

内容的提问来源于stack exchange,提问作者HittingMyCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:05:16