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

Spring HandleInterceptor设置Response Header无效的问题解决

问题:Spring Interceptor无法正确设置响应头ResponseId

代码实现

1. 测试Controller

@RestController
public class SpringController {
    @PostMapping(value="/test")
    public String test(){
        return "test";
    }
}

2. 自定义Interceptor

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class ControllerInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Pre-handle");
        System.out.println(request.getHeader("RequestId"));
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        response.setHeader("ResponseId", "2");
        System.out.println("Post-handle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        response.addHeader("ResponseId", "2");
        System.out.println(response.getHeader("ResponseId"));
        System.out.println("After completion");
    }
}   

3. Interceptor配置类

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class ControllerInterceptorAppConfig implements WebMvcConfigurer{
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ControllerInterceptor());
    }
}   

现象

在Postman中添加RequestId:1请求头后,终端打印:

Pre-handle
1
Post-handle
null
After completion

响应头ResponseId未出现在Postman的响应中,且终端打印null。

解决方案

问题原因

  1. afterCompletion阶段无法修改响应头:*afterCompletion*方法是在响应已经提交给客户端之后执行的,此时响应输出流已关闭,无法修改响应头,调用addHeader不会生效;同时响应提交后调用getHeader也无法获取已设置的头信息,所以打印出null。
  2. Interceptor实例创建不规范:配置类中手动new ControllerInterceptor(),但该类已标注@Component,手动new会导致实例脱离Spring容器管理(虽非本次头不生效的直接原因,但不符合规范)。

修复步骤

  1. 移除afterCompletion中对响应头的操作:仅在*postHandle*方法中设置响应头,该方法在处理器执行完成、响应尚未提交给客户端之前执行,此时修改响应头有效。
    修改后的Interceptor:

    @Component
    public class ControllerInterceptor implements HandlerInterceptor{
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("Pre-handle");
            System.out.println(request.getHeader("RequestId"));
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            response.setHeader("ResponseId", "2");
            System.out.println("Post-handle");
            // 可在此处打印验证头信息
            System.out.println(response.getHeader("ResponseId"));
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("After completion");
            // 禁止在此操作响应头
        }
    }   
    
  2. 规范Interceptor的注入方式:在配置类中通过依赖注入获取ControllerInterceptor实例,避免手动new:

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class ControllerInterceptorAppConfig implements WebMvcConfigurer{
        
        private final ControllerInterceptor controllerInterceptor;
    
        // 构造方法注入
        public ControllerInterceptorAppConfig(ControllerInterceptor controllerInterceptor) {
            this.controllerInterceptor = controllerInterceptor;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(controllerInterceptor);
        }
    }   
    

验证

修改完成后重启服务,用Postman发送请求,即可在响应头中看到ResponseId:2,终端也会打印正确的头信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:50:37