《Java 100 天进阶之路》第68篇:JavaWeb核心技术之Servlet(2026版) 第68篇JavaWeb核心技术之Servlet2026版系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第67篇JVM面试压轴题 |➡️ 下一篇第69篇JSP与EL表达式待发布️ 本文阅读地图3 分钟速览JVM调优专题已收官本篇开启JavaWeb专题。Servlet是Java Web开发的“地基”——Spring MVC、Spring Boot底层都是Servlet。理解Servlet才能真正理解Web框架模块核心问题一句话回答Servlet是什么Java Web的“地基”是什么运行在Web容器中的Java类处理HTTP请求并返回响应生命周期Servlet从生到死经历什么加载→实例化→init()→service()→destroy()核心对象请求和响应用什么对象HttpServletRequest请求、HttpServletResponse响应三大组件Servlet规范还有哪些组件Servlet Filter Listener三者分工协作异步处理Servlet 3.0带来了什么AsyncContext实现非阻塞处理释放容器线程Servlet vs Spring MVC现在还用Servlet吗Spring MVC底层仍是Servlet但封装了细节Jakarta EE迁移javax包去哪了从javax.servlet迁移到jakarta.servletJakarta EE 9面试最爱问高频考点有哪些见文末 小节一、核心知识点1. Servlet是什么ServletServer Applet是Java EE现Jakarta EE规范中定义的服务器端组件用于接收客户端请求并返回响应。它不依赖特定的平台或协议最常用的是HTTP Servlet。本质Servlet就是一个运行在Web容器Tomcat、Jetty等中的Java类遵循特定的生命周期规范。2. Servlet的核心地位Servlet是Java Web一切框架的底层基石无论是Spring MVC的DispatcherServlet还是Spring Boot的内嵌Tomcat底层都是Servlet。理解Servlet是理解一切Java Web框架的前提。3. 2026年重要背景Jakarta EE迁移从Jakarta EE 9开始所有javax.servlet包名改为jakarta.servlet。Servlet API版本演进Servlet 4.0Java EE 8javax.servletServlet 5.0Jakarta EE 9jakarta.servletServlet 6.0Jakarta EE 10去除SecurityManager相关API面试注意2026年新建项目应使用jakarta.servlet老项目迁移需注意包名变更。4. Servlet三大核心组件组件作用典型场景Servlet处理具体业务请求用户登录、订单查询Filter请求/响应预处理和后处理日志记录、编码过滤、权限校验Listener监听Web应用生命周期事件应用启动初始化、Session管理二、通俗讲解1分钟开心学把Servlet想象成餐厅的“服务员”客户端浏览器顾客坐在桌前要点菜发请求。Servlet服务员负责接收顾客的点菜单请求去厨房业务逻辑拿菜再把菜端给顾客响应。每个服务员只服务一位顾客一个请求对应一个Servlet实例的service方法调用。Filter餐厅门口的迎宾员。每个顾客进来先经过迎宾员检查——带口罩了吗有预约吗请求过滤走的时候迎宾员再说声“欢迎下次光临”响应后处理。Listener餐厅的传感器。餐厅开门了应用启动传感器记录有顾客进来了Session创建传感器记录餐厅关门了应用关闭传感器记录。Web容器Tomcat餐厅的管理系统负责招聘服务员创建Servlet实例、安排工作调用生命周期方法、辞退服务员销毁Servlet。一句话总结Filter管“进出门”Servlet管“核心服务”Listener管“全程监控”。三、Servlet生命周期Servlet生命周期由Web容器Tomcat等全权管理开发者不需要手动newServlet对象。3.1 生命周期四阶段各阶段详解阶段方法调用次数触发时机说明加载与实例化构造方法1次第一次请求到达默认或容器启动时默认懒加载可通过load-on-startup改为容器启动时加载初始化init()1次实例化后立即调用加载数据库连接池、配置文件等资源服务service()每次请求每次HTTP请求到达根据请求方法分发到doGet()/doPost()等销毁destroy()1次容器关闭或应用卸载时释放资源如关闭数据库连接重要理解Servlet是单例多线程——整个应用只有一个Servlet实例但每个请求会创建一个新线程调用service()方法。因此Servlet实例变量不是线程安全的3.2 代码示例importjakarta.servlet.*;importjakarta.servlet.http.*;importjakarta.servlet.annotation.*;importjava.io.*;WebServlet(/hello)publicclassHelloServletextendsHttpServlet{// ① 初始化执行一次Overridepublicvoidinit()throwsServletException{System.out.println(Servlet初始化加载资源);}// ② 服务每次请求执行OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{resp.setContentType(text/html;charsetUTF-8);PrintWriteroutresp.getWriter();out.println(h1Hello, Servlet!/h1);out.println(p当前时间newjava.util.Date()/p);}OverrideprotectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// POST请求处理doGet(req,resp);}// ③ 销毁执行一次Overridepublicvoiddestroy(){System.out.println(Servlet销毁释放资源);}}web.xml配置方式传统仍用于Servlet 6.0web-appservletservlet-namehello/servlet-nameservlet-classcom.example.HelloServlet/servlet-classload-on-startup1/load-on-startup!-- 容器启动时加载 --/servletservlet-mappingservlet-namehello/servlet-nameurl-pattern/hello/url-pattern/servlet-mapping/web-app四、核心对象Request Response4.1 HttpServletRequest——请求对象方法作用getParameter(String name)获取单个请求参数getParameterMap()获取所有请求参数MapgetHeader(String name)获取请求头getSession()获取/创建SessiongetRequestDispatcher()请求转发setAttribute(String, Object)设置请求属性转发传递数据startAsync()Servlet 3.0启动异步处理4.2 HttpServletResponse——响应对象方法作用setContentType(String)设置响应内容类型如text/html;charsetUTF-8setStatus(int)设置HTTP状态码getWriter()获取字符输出流输出HTMLgetOutputStream()获取字节输出流输出文件/图片sendRedirect(String)重定向302addCookie(Cookie)添加Cookie4.3 请求转发 vs 重定向对比请求转发forward重定向sendRedirect浏览器地址栏不变变化请求次数1次服务器内部2次客户端重新发起数据共享✅ 可共享request属性❌ 不可共享性能更高少一次请求较低多一次请求适用场景服务器内部跳转页面跳转、防止表单重复提交五、Servlet 3.0 异步处理5.1 为什么需要异步传统Servlet模型中一个请求占用一个容器线程直到处理完成。如果业务有耗时操作如调用外部API、大文件处理容器线程会被长时间占用导致并发能力下降。Servlet 3.0引入异步处理将耗时任务交给新线程释放容器线程处理其他请求提升吞吐量。5.2 异步Servlet实战importjakarta.servlet.*;importjakarta.servlet.http.*;importjakarta.servlet.annotation.*;importjava.util.concurrent.*;WebServlet(value/async,asyncSupportedtrue)// 关键启用异步publicclassAsyncServletextendsHttpServlet{privateExecutorServiceexecutorExecutors.newFixedThreadPool(10);OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 1. 启动异步上下文AsyncContextctxreq.startAsync();//// 2. 提交耗时任务到线程池executor.submit(()-{try{// 模拟耗时操作如调用外部API、查询数据库Thread.sleep(3000);// 3. 获取响应并输出HttpServletResponseresponse(HttpServletResponse)ctx.getResponse();response.setContentType(text/plain;charsetUTF-8);response.getWriter().println(异步处理完成);}catch(Exceptione){e.printStackTrace();}finally{// 4. 完成异步处理ctx.complete();}});// 容器线程立即释放不阻塞}}关键点asyncSupported true启用异步startAsync()获取AsyncContext耗时任务在新线程执行完成后调用complete()。六、三大组件Filter Listener6.1 Filter——请求拦截器Filter是Servlet规范的一部分在请求到达Servlet之前和响应返回客户端之后执行。典型场景日志记录、统一编码处理、登录验证、跨域处理、敏感词过滤。importjakarta.servlet.*;importjakarta.servlet.annotation.*;importjava.io.IOException;WebFilter(/*)// 拦截所有请求publicclassLogFilterimplementsFilter{Overridepublicvoidinit(FilterConfigconfig)throwsServletException{System.out.println(Filter初始化);}OverridepublicvoiddoFilter(ServletRequestreq,ServletResponseresp,FilterChainchain)throwsIOException,ServletException{// 前置处理System.out.println(请求到达System.currentTimeMillis());// 放行到下一个Filter或Servletchain.doFilter(req,resp);// 后置处理System.out.println(响应返回System.currentTimeMillis());}Overridepublicvoiddestroy(){System.out.println(Filter销毁);}}Filter链执行顺序多个Filter按WebFilter的filterName字母顺序或web.xml配置顺序执行形成责任链。6.2 Listener——事件监听器Listener监听Web应用中关键对象的生命周期事件。三种核心ListenerListener监听对象典型场景ServletContextListener应用上下文启动/关闭加载配置文件、初始化数据库连接池HttpSessionListenerSession创建/销毁在线用户统计ServletRequestListener请求创建/销毁请求日志记录importjakarta.servlet.*;publicclassAppListenerimplementsServletContextListener{OverridepublicvoidcontextInitialized(ServletContextEventsce){System.out.println(应用启动加载配置...);// 加载数据库连接池、Spring容器等}OverridepublicvoidcontextDestroyed(ServletContextEventsce){System.out.println(应用关闭释放资源...);}}七、Servlet vs Spring MVC对比维度ServletSpring MVC定位Java Web底层规范基于Servlet的高级Web框架开发方式继承HttpServlet手动配置映射注解驱动Controller、RequestMapping参数绑定手动req.getParameter()自动绑定到方法参数视图渲染手动拼接HTML或用JSP自动渲染支持多种视图技术启动速度快较慢需加载Spring上下文内存占用低高适用场景理解底层、轻量级应用绝大部分企业级应用核心结论Spring MVC底层是DispatcherServlet它本身就是一个Servlet。掌握了Servlet就掌握了Spring MVC的“发动机”。八、避坑要点错误/误区后果正确做法Servlet实例变量非线程安全多线程数据混乱尽量用局部变量避免在Servlet中定义可变的实例变量忘记asyncSupported true异步功能不生效注解中加上asyncSupported trueFilter中不调用chain.doFilter()请求被拦截无法到达目标必须调用chain.doFilter()放行请求转发和重定向混淆数据丢失或重复提交转发用forward重定向用sendRedirect忘记设置setContentType中文乱码统一设置text/html;charsetUTF-8老项目使用javax.servlet不兼容Jakarta EE 9新项目使用jakarta.servlet九、面试高频考点Q1Servlet的生命周期有哪些阶段四个阶段①加载与实例化容器创建Servlet实例②初始化调用init()执行一次③服务调用service()每次请求执行④销毁调用destroy()执行一次。Q2Servlet是单例还是多例线程安全吗Servlet是单例整个应用只有一个实例。线程不安全——多个请求共享同一个Servlet实例实例变量会被多线程共享。因此应避免在Servlet中使用可变的实例变量尽量使用局部变量。Q3Filter和Interceptor的区别Filter是Servlet规范的一部分运行在Web容器中在请求到达Servlet之前执行。Interceptor是Spring MVC的组件运行在Spring容器中在Handler执行前后执行。Filter更底层Interceptor功能更丰富可注入Spring Bean。Q4请求转发forward和重定向redirect的区别转发forward是服务器内部跳转地址栏不变1次请求可共享request属性。重定向redirect是客户端重新发起请求地址栏变化2次请求不可共享request属性。Q5javax.servlet和jakarta.servlet有什么区别Jakarta EE 9开始所有javax包名改为jakarta。新项目使用jakarta.servlet。老项目迁移需修改import和依赖版本。 面试官追问陷阱加分题追问1“Servlet 3.0的异步处理中startAsync()之后容器线程会怎样” 容器线程立即释放回到线程池处理其他请求。耗时任务在AsyncContext关联的新线程中执行。完成后调用complete()通知容器。追问2“load-on-startup设置为正数和负数有什么区别” 正数容器启动时加载Servlet数值越小优先级越高。负数或未设置懒加载——第一次请求到达时才创建Servlet实例。十、练习题代码题编写一个Servlet接收name参数返回“Hello, [name]”的HTML页面。分析题Filter和Servlet的执行顺序是什么一个请求经过多个Filter时顺序如何确定场景题某Web应用需要统计在线用户数应该使用什么组件如何实现 你的学习进度当前第68篇 / 共108篇 ·进阶篇JavaWeb核心技术第68~72篇✅ 已完成基础篇44篇 第45~68篇 正在学第68篇⏳ 待学习第69~108篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 下一篇文章预告下一篇《第69篇JSP与EL表达式》内容简介JSP原理、九大内置对象、EL表达式语法、JSTL标签库、JSP与Servlet的关系。JavaWeb专题持续深入拿下JSP与EL《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送