那请你给我介绍一下servlet container的运行流程

下面给你的是容器实现者级别的 Servlet Container 运行模型。

不讲 Tomcat 参数、不讲 web.xml,只讲它内部是如何驱动一次 HTTP 请求的。





一句话总览



Servlet Container 是一个“HTTP → 线程 → Filter → Servlet → Response”的调度内核。


Spring、Spring MVC、Spring Security,全都只是挂在它后面的插件。





一、整体执行路径



一次 HTTP 请求在容器中的真实路径是:

TCP 连接

 ↓

HTTP 解析(Connector)

 ↓

Socket → Request / Response 对象

 ↓

分配工作线程(Executor)

 ↓

Engine

 ↓

Host(虚拟主机)

 ↓

Context(WebApp)

 ↓

Wrapper(Servlet)

 ↓

FilterChain

 ↓

Servlet.service()

 ↓

Controller

Spring 只在 Servlet 之后。





二、线程模型(你性能的根源)



以 Tomcat 为例:

Acceptor 线程  → 接 TCP

Poller    线程  → 监听 Socket 可读

Worker    线程  → 处理请求

当 Socket 可读:

Poller → 把 Socket 丢给 Executor → 一个 Worker 线程

这个 Worker 线程贯穿整个请求生命周期。


这就是为什么:


  • Servlet 是阻塞模型
  • Spring MVC 是线程绑定模型
  • Spring Security 用 ThreadLocal






三、Request 是如何被路由的



当线程接管请求后:

Engine

 → 找域名

Host

 → 找 Context path

Context

 → 找 URL pattern

Wrapper

 → 找 Servlet

这是:

example.com/app/api/user

         └─ Context

               └─ /api/*

                      └─ DispatcherServlet





四、FilterChain:一切中间件的根



在 Servlet 之前:

Request

 → Filter1

   → Filter2

     → Filter3

       → Servlet

     ←

   ←

 ←

Filter 可以:


  • 修改 Request
  • 拦截
  • 重定向
  • 包装 Response



Spring Security 就是一个超级 Filter。





五、DispatcherServlet 在容器中的真实地位



从容器视角:

Tomcat

 → DispatcherServlet(普通 Servlet)

     → HandlerMapping

     → HandlerAdapter

     → Controller

Tomcat 完全不知道:


  • @Controller
  • @RestController
  • @RequestMapping



它只知道:


“我在调用一个 Servlet 的 service()”





六、为什么 Session、Security、事务都能工作



因为:

一个请求 = 一个线程

一个线程 = 一个 ThreadLocal 容器

Spring 用这个模型存:


  • SecurityContext
  • Transaction
  • RequestContext



这是 Servlet 规范最重要的隐含契约。





七、为什么 WebFlux 不用 Servlet



Servlet 模型:


一个请求霸占一个线程


WebFlux(Netty):


一个线程处理成千上万连接


但 Spring MVC、Spring Security 的经典模型是建立在 Servlet 线程模型之上的。





八、终极工程结论



Servlet Container 是 Java Web 世界真正的操作系统内核。


Spring 只是跑在它之上的应用框架。


你只要记住一条主线就够了:

Socket → Thread → FilterChain → Servlet → Spring → Controller

如果你愿意,我可以下一步给你画:


  • Spring Security 在 FilterChain 中的准确位置
  • 或 Tomcat vs Netty 的执行路径对比
  • 或 为什么虚拟线程正在改变 Servlet 容器的未来




filter中可以做哪些操作

这是一个非常关键的问题。

Filter 能做什么,决定了 Spring Security、日志、网关、限流、审计、甚至 WAF 能做什么。


我给你一份容器级能力清单。





一句话总览



Filter 是 Servlet 容器赋予你的“内核态钩子”。


它可以在 Controller 之前和之后:


  • 查看
  • 修改
  • 替换
  • 阻断
    整个 HTTP 请求与响应。






一、Filter 能接触到什么



在 doFilter(request, response, chain) 中你能拿到:



请求侧



  • URL / QueryString
  • Headers
  • Cookies
  • Body(InputStream)
  • Remote IP
  • TLS 信息
  • Session




响应侧



  • Status code
  • Headers
  • Cookies
  • Body(OutputStream)
  • Redirect
  • Commit 状态






二、Filter 能做的核心操作




1️⃣ 直接放行(什么都不做)


chain.doFilter(req, resp);

这是 99% 请求的路径。





2️⃣ 阻断请求(安全与风控)


resp.sendError(401);

return;

常见用途:


  • 认证失败
  • 黑名单 IP
  • CSRF
  • WAF



Spring Security 就是干这个。





3️⃣ 修改 Request(伪造客户端)


HttpServletRequestWrapper

可以:


  • 添加 Header
  • 改参数
  • 替换 Body



例如:


  • JWT → 注入 userId
  • Gateway → 注入租户 ID
  • 反向代理






4️⃣ 修改 Response(统一出口)



你可以:


  • 包一层 HttpServletResponseWrapper
  • 改返回 JSON
  • 注入 header
  • 压缩 / 加密



例如:


  • 全站加 X-Trace-Id
  • 错误统一格式






5️⃣ 接管整个请求(短路)



你可以:

resp.getWriter().write("blocked");

return;

Controller 完全不会执行。


网关、Mock Server、熔断器都这么干。





6️⃣ 捕获异常(全局兜底)


try {

   chain.doFilter(...)

} catch (Exception e) {

   log(e);

   writeError(resp);

}

比 Spring @ControllerAdvice 还早。





7️⃣ 记录与审计



你可以:


  • 读 body
  • 记 header
  • 记用户
  • 记响应



这是:


  • 日志
  • 审计
  • 风控
  • APM 的基础






三、Filter 为什么这么强



因为它运行在:

Socket 已建立

Controller 尚未执行

这是 Web 世界唯一的“特权位置”。


你可以:


  • 改事实(Request)
  • 改结果(Response)
  • 改命运(放行 or 拒绝)






四、Spring Security 为什么一定用 Filter



因为只有 Filter:


  • 能挡住 Controller
  • 能接管 Session
  • 能统一入口
  • 能跨所有 URL



如果放在 Controller:


攻击请求已经进来了。





五、Filter 的真正边界



Filter 不能:


  • 控制 TCP
  • 控制 TLS
  • 控制 HTTP 解析
  • 控制路由到哪个虚拟主机



那是 Connector 层的事。





六、终极结论



Filter 是 Java Web 的“内核模块”。


理解 Filter,你就理解了:


  • Spring Security
  • API Gateway
  • 网关
  • 登录系统
  • 限流
  • WAF
  • 统一认证



如果你愿意,我可以下一步给你:


  • Spring Security 中 15 个 Filter 的真实执行顺序
  • 或 你自己写一个 JWT Filter 的标准架构
  • 或 Filter vs Interceptor vs AOP 的真实边界



filter里阻断请求是指什么? 可以修改了response后就直接return吗

这是一个关键且容易被误解的点,你问得非常准确。





一句话结论



是的,在 Filter 里你可以在写完 Response 后直接 return,这就叫“阻断请求”。


它的效果是:


这个 HTTP 请求被你“终结”在 Filter 层,后面的 Filter、Servlet、Controller 全部不会执行。





一次请求的两条命运



在 Filter 中,一个请求只有两种走法:

A) chain.doFilter(req, resp)  → 继续向下走

B) 不调用 chain.doFilter     → 请求在这里终止

你只要不调用 chain.doFilter,你就已经“拦截”了它。





二、阻断请求的真实含义



比如你在 Spring Security 里:

if (!authenticated) {

   resp.setStatus(401);

   resp.getWriter().write("Unauthorized");

   return;

}

chain.doFilter(req, resp);

发生了什么:

Client → Filter

          ↳ 写 401

          ↳ return

Tomcat 认为:Response 已经完成

Controller 永远不会执行

这就是:


  • 未登录
  • 没权限
  • CSRF 失败
  • 黑名单 IP
  • Token 失效



的底层机制。





三、你可以在 Filter 里做哪些“终结型操作”



你可以:

操作作用
resp.sendError(403)直接拒绝
resp.sendRedirect()重定向
resp.getWriter().write()直接返回 JSON
resp.setStatus(401)设置 HTTP 结果
resp.setHeader()设置响应头

然后:

return;

请求生命周期就结束了。





四、Servlet 容器如何理解这个 return



容器只关心一件事:


“你有没有调用 chain.doFilter()?”


没有 = 你截断了链。


之后:


  • Tomcat 会把 Response flush 给客户端
  • Socket 关闭或复用
  • 请求结束






五、为什么这比 Controller 抛异常更强



Controller 层:


请求已经进入业务系统


Filter 层:


请求还在“门口”


所以:


  • WAF
  • Auth
  • Gateway
  • IP 限制



只能放在 Filter。





六、一个极重要的注意点




⚠️ 一旦你写了 response,就不要再调用 chain.doFilter()



否则你会得到:


  • “Response already committed”
  • 内容混乱
  • 安全漏洞



正确模式永远是:

if (block) {

   writeResponse();

   return;

}

chain.doFilter(...);





七、工程结论



Filter 是 HTTP 请求的“生死裁判”。


你在这里 return,

Controller 连“知道你来过”都不会知道。


如果你愿意,我可以下一步给你:


  • Spring Security 是在哪个 Filter 里做这个 return 的
  • 或 JWT Filter 正确阻断的标准写法
  • 或 Tomcat 在 response commit 之后发生了什么