在SpringBoot应用开发中,从HTTP请求头(Header)中获取信息是一项非常常见的需求,比如提取登录用户的token、追踪链路ID、获取客户端标识等。拦截器(Interceptor)作为Spring MVC提供的扩展机制,可以在请求到达Controller之前进行统一处理,非常适合用来读取Header并执行鉴权、日志记录等操作。本文将围绕如何使用SpringBoot拦截器获取Header内容展开,从基础实现到常见问题逐一说明。

基础实现:自定义拦截器获取Header
在SpringBoot中,创建一个拦截器需要实现 HandlerInterceptor 接口,并重写 preHandle 方法。该方法会在请求处理之前被调用,参数中包含了 HttpServletRequest 对象,通过它可以轻松获取请求头信息。下面是一个简单的示例,演示如何获取名为 Authorization 的Header值:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class HeaderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authHeader = request.getHeader("Authorization");
if (authHeader != null) {
System.out.println("Authorization Header: " + authHeader);
// 可以在这里进行token校验等操作
}
return true; // 返回true表示继续执行后续拦截器和处理器
}
}
需要注意的是,preHandle 方法返回 true 时请求才会继续向下传递;如果返回 false,请求将被终止,后续的拦截器和Controller都不会执行。在实际项目中,通常根据Header中的token判断用户是否已登录,未登录时可以直接返回错误响应。
创建好拦截器类后,还需要将其注册到Spring MVC的拦截器链中。这可以通过实现 WebMvcConfigurer 接口并重写 addInterceptors 方法来完成。以下是一个配置类示例:
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 WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HeaderInterceptor())
.addPathPatterns("/**"); // 拦截所有路径
// 也可以使用.excludePathPatterns("/login", "/public/**")排除某些路径
}
}
上述配置将 HeaderInterceptor 应用于所有请求路径。你可以根据业务需要调整拦截范围,例如只拦截需要鉴权的接口。另外,addPathPatterns 和 excludePathPatterns 支持通配符,使用起来非常灵活。
关于Header名称的大小写问题:根据HTTP规范,Header字段名是不区分大小写的。Servlet容器在解析请求头时通常会保留原始的大小写,但通过 getHeader 方法获取时,内部会进行不区分大小写的匹配。因此,无论你传入 Authorization 还是 authorization,都能正确获取到值。不过为了代码可读性,建议统一使用标准的驼峰命名。
深入对比:拦截器与过滤器获取Header的差异
很多开发者在初次接触请求头获取时会困惑:到底该用过滤器(Filter)还是拦截器(Interceptor)?两者都可以在请求处理前拿到Header,但在实现机制和适用场景上存在明显区别。
过滤器是Servlet规范的一部分,运行在Servlet容器级别,它先于Spring MVC的 DispatcherServlet 执行。过滤器中的 doFilter 方法同样可以获取 HttpServletRequest 对象并读取Header。拦截器则是Spring MVC框架提供的组件,它运行在 DispatcherServlet 之后,在Controller方法调用之前执行。拦截器可以方便地访问Spring容器中的Bean(通过依赖注入),而过滤器由于不在Spring上下文中,需要额外的配置才能使用Spring管理的对象。
从获取Header的API角度看,两者使用的都是 HttpServletRequest,代码几乎一样。但拦截器的优势在于更紧密地集成Spring生态,例如可以直接使用 @Autowired 注入服务类,方便进行权限校验、日志记录等。过滤器则更适合处理一些与Spring无关的通用任务,如编码设置、跨域处理、请求日志等。如果项目已经采用SpringBoot,并且需要获取Header并结合业务逻辑(如查询数据库验证token),使用拦截器会更加自然。
下面通过一个简单的过滤器示例来对比。过滤器需要实现 javax.servlet.Filter 接口,并通过 @Component 或配置类注册:
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String header = httpRequest.getHeader("X-Custom-Header");
System.out.println("Filter获取Header: " + header);
chain.doFilter(request, response); // 继续过滤链
}
}
可以看到,过滤器需要手动转换类型,并且如果需要在过滤器中使用Spring Bean,必须通过其他方式(如实现 ApplicationContextAware)获取,相对麻烦。因此,对于纯粹获取Header并传递给后续处理的场景,拦截器是更推荐的选择。
常见问题与注意事项
在实际开发中,使用拦截器获取Header时经常会遇到一些问题,下面梳理几个高频问题及其解决方案。
问题一:获取到的Header为null。出现这种情况通常有几个原因:第一,请求方根本没有携带该Header,可以通过浏览器开发者工具或抓包工具确认;第二,Header名称拼写错误,虽然不区分大小写,但拼写错误仍然会导致无法匹配;第三,请求经过了反向代理或网关,某些Header可能被过滤或重命名,例如Nginx默认会隐藏带下划线的Header,需要配置 underscores_in_headers on。排查时可以在拦截器中打印所有Header名称和值,快速定位问题。
import java.util.Enumeration;
// 打印所有请求头
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String value = request.getHeader(name);
System.out.println(name + ": " + value);
}
问题二:如何获取多个同名Header。HTTP协议允许同一个Header名称出现多次,例如多个 Set-Cookie 或自定义的 X-Forwarded-For。使用 getHeader 方法只会返回第一个值。如果需要获取所有值,可以使用 getHeaders 方法,它返回一个 Enumeration 对象。在Spring MVC中,也可以使用 HttpHeaders 类配合 @RequestHeader 注解,但拦截器中通常直接操作 HttpServletRequest,此时应使用 getHeaders。
import java.util.Enumeration;
Enumeration<String> values = request.getHeaders("X-Forwarded-For");
while (values.hasMoreElements()) {
String val = values.nextElement();
System.out.println("X-Forwarded-For value: " + val);
}
问题三:拦截器执行顺序与异步请求。多个拦截器按照注册顺序依次执行 preHandle,而 postHandle 和 afterCompletion 则按照相反顺序执行。在异步请求(返回 Callable 或 DeferredResult)中,afterCompletion 可能在异步线程完成后才调用,此时 preHandle 中设置的 ThreadLocal 变量可能无法传递到异步线程,需要特别小心。如果必须在异步场景下传递Header信息,建议使用 RequestContextHolder 或显式传递参数。
注意事项:安全与性能。在拦截器中读取Header时,避免记录敏感信息(如 Authorization、Cookie)到日志,防止泄露。同时,拦截器中的逻辑应尽量轻量,避免执行耗时操作(如远程调用、复杂计算),因为 preHandle 会阻塞请求处理线程。如果确实需要执行耗时校验,可以考虑使用异步处理或缓存机制。
此外,拦截器不能直接修改请求的Header,因为 HttpServletRequest 对象通常是不可变的。如果需要向后续处理传递数据,可以将数据放入 request.setAttribute 中,或者在 preHandle 中将值存入 ThreadLocal 并在 afterCompletion 中清理,但要注意线程安全和内存泄漏问题。
SpringBoot拦截器Header获取请求头修改时间:2026-09-19 13:06:54