源码分析:Tomcat - 请求Header异步获取不到问题 发表于 2025-08-01 | 分类于 ---SpringBoot , ---源码 | 前言12345678910111213141. 为什么需要这个?请求在结束时,header会清空,异步再从请求中获取header内容,就获取不到了。 org.apache.coyote.http11.Http11Processor.recycle --- inputBuffer.recycle(); org.apache.coyote.http11.Http11InputBuffer.recycle --- request.recycle(); org.apache.coyote.Request.recycle --- headers.recycle(); org.apache.tomcat.util.http.MimeHeaders.recycle2. 大小写问题解析转为小写 --- org.apache.coyote.http11.Http11InputBuffer.parseHeader // chr is next byte of header name. Convert to lowercase. if (chr >= Constants.A && chr <= Constants.Z) { byteBuffer.put(pos, (byte) (chr - Constants.LC_OFFSET)); }header 获取忽略大小写 --- org.apache.tomcat.util.http.MimeHeaders.getHeader 上下文-放入省略其他代码 12345678910111213141516171819202122232425262728293031323334@Slf4j@Order(2)@Componentpublic class TokenFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { try { ContextUtils.Header.init(); // [3] 执行下一个拦截器 filterChain.doFilter(servletRequest, servletResponse); } finally { ContextUtils.Header.remove(); } }}public class AsyncUtils { public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) { final LinkedCaseInsensitiveMap<String> header = ContextUtils.Header.get(); return CompletableFuture.supplyAsync(() -> { try { ContextUtils.Header.set(header); return supplier.get(); } finally { ContextUtils.Header.remove(); } }, executor); }} 上下文-获取1234567891011121314151617181920public class UserUtil { private static String header(String key) { return Opt.ofTry(() -> ContextUtils.Header.get().get(key)).get(); } // ios/android/h5 public static String platform() { return header("platform"); } // 设备ID public static String deviceId() { return header("deviceId"); } public static String userAgent() { return header("User-Agent"); }} 上下文-定义123456789101112131415161718192021222324252627282930public class ContextUtils { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 请求header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ public static class Header { private static ThreadLocal<LinkedCaseInsensitiveMap<String>> header = ThreadLocal.withInitial(LinkedCaseInsensitiveMap::new); public static void init() { LinkedCaseInsensitiveMap<String> value = Header.get(); UserUtil.request().getHeaderNames().asIterator().forEachRemaining(key -> { value.put(key, UserUtil.request().getHeader(key)); }); Header.header.set(value); } public static void set(LinkedCaseInsensitiveMap<String> value) { header.set(value); } public static LinkedCaseInsensitiveMap<String> get() { return header.get(); } public static void remove() { header.remove(); } }}