别再死记硬背了!用Tomcat 10 + IDEA手把手带你理解Servlet和JSP到底怎么工作
别再死记硬背了用Tomcat 10 IDEA手把手带你理解Servlet和JSP到底怎么工作刚接触JavaWeb开发时很多人会被Servlet和JSP的各种概念搞得晕头转向。生命周期、九大内置对象、MVC模式...这些教科书式的术语堆砌往往让人越看越迷糊。今天我们就换一种方式——打开IDEA启动Tomcat用可视化调试的方式带你亲眼看看一个HTTP请求是如何被处理的。1. 环境准备搭建可调试的实验室工欲善其事必先利其器。我们先准备好以下工具IntelliJ IDEA Ultimate 2023社区版也可用但功能略少Tomcat 10.1.x注意与JDK版本的兼容性JDK 17LTS版本推荐使用1.1 创建Web项目在IDEA中新建项目时选择New Project → Jakarta EE → Web Application勾选Create web.xml选项虽然Servlet 5.0支持注解配置但保留它有助于理解传统配置方式。项目创建完成后检查目录结构src ├── main │ ├── java # Servlet源代码 │ ├── resources # 配置文件 │ └── webapp # 前端资源 │ ├── WEB-INF │ │ └── web.xml │ └── index.jsp1.2 配置Tomcat服务器打开Run/Debug Configurations添加Tomcat Server → Local在Deployment标签页添加项目war包关键步骤勾选Show dialog when application stops这样当我们在调试时暂停程序浏览器请求会被挂起方便观察中间状态提示建议修改Tomcat的conf/logging.properties文件将日志级别调整为FINE可以看到更详细的处理流程。2. 解剖Servlet从请求到响应的完整旅程让我们创建一个最简单的Servlet来观察生命周期WebServlet(/demo) public class LifeCycleServlet extends HttpServlet { Override public void init() { System.out.println(【Init】Servlet被容器初始化); } Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { System.out.println(【Service】处理GET请求); resp.getWriter().println(h1Hello from Servlet/h1); } Override public void destroy() { System.out.println(【Destroy】Servlet即将被销毁); } }2.1 调试观察点设置在IDEA中设置以下断点init()方法第一行doGet()方法第一行resp.getWriter().println()这一行启动调试模式访问http://localhost:8080/demo你会看到首次访问时Tomcat会先调用init()然后执行doGet()后续访问直接进入doGet()服务器关闭时触发destroy()注意在web.xml中配置load-on-startup1/load-on-startup可以改变初始化时机。3. JSP的魔法面具揭开编译背后的真相很多人以为JSP就是HTML里写Java其实它会被Tomcat转换成Servlet。让我们验证这一点创建time.jsp% page contentTypetext/html;charsetUTF-8 % html head title时间展示/title /head body 当前时间% new java.util.Date() % /body /html3.1 查看编译结果访问该页面后打开Tomcat的work/Catalina/localhost目录找到对应项目目录下的org/apache/jsp子目录你会看到生成的time_jsp.java文件关键代码片段public void _jspService(HttpServletRequest request, HttpServletResponse response) { // 自动生成的页面上下文和输出流 PageContext pageContext _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); JspWriter out pageContext.getOut(); // 我们的JSP内容被转换成了Java代码 out.write(html...); out.print(new java.util.Date()); out.write(/body/html); }3.2 九大内置对象的真相在生成的Servlet中可以看到这些对象其实都是_jspService方法的局部变量final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out null; final java.lang.Object page this; // ...4. 全流程跟踪一个请求的奇幻漂流现在我们把所有环节串联起来用调试模式完整跟踪一个请求浏览器发起请求访问http://localhost:8080/greet?nameAliceTomcat接收请求在org.apache.catalina.core.ApplicationFilterChain的doFilter方法设断点Servlet处理阶段观察HttpServletRequest对象如何解析参数转向JSP在Servlet中使用request.getRequestDispatcher(result.jsp).forward(req, resp)JSP渲染查看_jspService方法如何组合最终HTML4.1 关键对象状态记录表阶段关键对象重要状态变化请求到达HttpServletRequestmethodGET, queryStringnameAliceServlet处理HttpServletResponsecontentType未设置buffer为空JSP渲染PageContext初始化out、session等内置对象响应返回HttpServletResponsecontentTypetext/html, buffer已填充5. 实战技巧常见问题排查指南5.1 为什么我的Servlet没响应检查清单WebServlet注解路径或web.xml配置是否正确项目是否成功部署到Tomcat的webapps目录控制台是否有ClassNotFoundException5.2 JSP显示源码而不是执行可能原因Tomcat的JSP引擎未正确配置文件没有放在webapp目录下文件扩展名不是.jsp5.3 调试时看不到变量值解决方案确保使用Debug模式启动Tomcat检查IDEA的Build → Rebuild Project在断点处右键选择Make Default确保所有线程暂停6. 进阶探索自定义JSP标签实战理解了原理后我们可以尝试更高级的应用。创建一个显示当前时间的自定义标签定义标签处理器public class NowTag extends SimpleTagSupport { Override public void doTag() throws JspException { getJspContext().getOut().print(new Date()); } }在WEB-INF/tags下创建mytag.tag% tag body-contentempty % % attribute nameformat requiredfalse typejava.lang.String % jsp:invoke fragmenttimeFragment/在JSP中使用% taglib prefixmy tagdir/WEB-INF/tags % my:now formatyyyy-MM-dd/通过这个案例你会发现JSP标签本质上也是被转换成了Servlet代码只不过封装了更复杂的逻辑。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2497143.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!