1.3 第一次跑通——环境搭建与首个动态页面


1.3 第一次跑通——环境搭建与首个动态页面

本节摘要:让一个 JSP 站点在本机跑起来只需要四步——选对容器版本、按约定摆好目录、部署应用、发起访问;但每一步都有老站点特有的坑。本节带你从零搭出青梧书肆的本地运行环境,并在浏览器里看到第一个属于你的动态输出。这一步是全书的地基:后面九章的所有演练、重构、排错,都发生在这台环境上。

先选容器:版本决定一切

上一节的三问断代法,第一站就用上了。青梧书肆的代码大量使用 javax 命名空间(1.2 节说过,这是 Jakarta 更名前的老前缀),那么容器就必须选仍然认 javax 的最后一代主流版本——Tomcat 9 系列。 Tomcat 从 10 开始强制迁移到 jakarta 前缀,把老工程丢进去,所有页面直接报类找不到的错。这是接手老站的第一条选型纪律:容器版本跟着代码的命名空间走,不跟着潮流走

容器之外还有 Java 版本的配套问题。Tomcat 9 要求 Java 8 及以上,而太新的 JDK 反而可能让一些老构建脚本水土不服。稳妥的组合是:容器 9.x,Java 11,这是目前维护 javax 世代老站最省心的搭配。版本对应关系记一张小表就够:

组件 推荐版本 为什么是它
容器 Tomcat 9.x 最后一代默认支持 javax 命名空间的主流容器
Java JDK 11 满足容器要求,又不过分超前,对老构建脚本友好
操作系统 任意主流桌面系统 JSP 生态跨平台,本节步骤在三大系统上一致

安装本身没有可说的:解压即用,这也是容器流行的历史原因之一。解压完,你会得到几个一眼就能望穿意图的目录——存放站点应用的目录、存放日志的目录、放启动停止脚本的目录。花五分钟把每个目录点开看一眼,比读十页文档有效。

摆目录:容器只认约定

容器对站点结构有一套死板却清晰的约定,违反约定是新手 404 的头号来源。把约定画出来,一眼就能对照检查。

图1-3 一个站点工程的标准骨架

图1-3 一个站点工程的标准骨架

约定只有三条值得背下来。第一,公开目录里的东西浏览器直接可达,访问地址就是应用前缀加相对位置。第二,私有目录名固定为 WEB-INF,容器拒绝一切对它的直接访问,你的配置文件、编译后的类、第三方依赖包都住在这里面。第三,应用可以整个打成 war 包丢进容器,也可以以目录形式摆放,两种形态容器都认。

部署与访问:四步里最短的 两步

把青梧书肆的站点目录整个拷进容器的应用目录(假设命名前缀为 bookstore),启动容器,理论上就完事了。启动脚本各平台不同,但判定成败的标准一致:日志里出现部署完成与端口监听就绪的字样。默认端口是 8080,被占用就改配置文件里的端口号——这是新手第一次撞墙的高发点,日志会明确告诉你端口冲突,别慌。

打开浏览器,敲入本机地址加应用前缀,比如指向站点的首页。这时通常有三种结果:页面正常出现;404;500。404 和 500 的排查思路值得当场走一遍,因为这就是你未来线上排障的日常动作。

背景:部署完成后访问首页,浏览器报 404,而文件明明就摆在公开目录里。

操作:按顺序查三处。一看日志有没有"部署 bookstore 失败"字样——没有,说明容器认为部署成功了;二确认访问地址的前缀拼写与应用目录名完全一致;三检查首页文件名与容器欢迎页配置是否对得上。

结果:发现工程根本没有欢迎页配置,而首页文件名不叫约定俗成的 index,叫 home。直接访问完整地址,页面出现。

解读:404 在这里不是"应用没部署",而是"地址没有对应到具体资源"。容器只在欢迎页配置命中的文件名上才肯替你省略文件名。这类问题的价值在于逼你第一次意识到:浏览器地址栏里的每个字符,都在容器里对应一次精确的查表动作。第 2 章的请求旅程会把这个查表过程完整拆开。

变式:如果你看到的是 500 而非 404,说明请求已经进到了页面、执行时出了异常——那反而是好消息,说明链路通了,问题变成了代码问题,翻日志找异常栈即可。

第一个动态页面:亲手验证 1.1 的翻译机制

环境通了,写一个十行的页面验证上一节的图景。在 bookstore 的公开目录里建一个 clock.jsp:

<%@ page contentType="text/html; charset=UTF-8" %> <html> <body> <h2>青梧书肆 · 服务器时钟</h2> <p>当前服务器时间:<%= new java.util.Date() %></p> <p>会话编号:<%= session.getId() %></p> <p>你的地址:<%= request.getRemoteAddr() %></p> </body> </html>

访问它,刷新几次。时间在走,说明这段代码每次请求都在服务器上重新执行——这就是 1.1 节说的"翻译后的类的服务方法在反复运行";会话编号在你连续刷新时保持不变,这是服务器发给你的身份凭证,它背后的会话机制是第 2 章的主角之一。一个十行的页面,把三章的知识串成了你亲眼所见的事实。

💡 关键直觉:环境搭建的本质是让"你写的文本"和"容器执行的类"这两个世界接上电。以后遇到任何环境类故障,先分清问题出在文本世界(编译不过、找不到文件)还是类世界(运行异常、内存溢出),一半的迷茫会当场消失。

上手自检:五种最常见的启动失败

环境交接的质量,取决于接手者卡壳时有没有对照表。五种高发失败与对应的自查顺序如下。其一,容器启动即退出——先看日志首行,八成是端口被占或运行时版本不匹配,改端口或换运行时即可。其二,启动正常但访问一律拒绝——检查应用是否真的部署成功,日志里搜索部署应用的名称,部署失败会在启动阶段写明原因。其三,页面出现但中文乱码——回头翻 3.2 节的编码双声明,多半是页面没写编码而容器默认值与文件实际编码不一致。其四,改了页面不见效果——2.1 节的时间戳陷阱,确认文件真的改到了容器正在用的那份。其五,时报错时不报错——八成是本地数据不完整,某些页面依赖的记录缺失,按页面提示反查数据脚本。

把这五条写进交接文档的"常见坑速查",新同事的求助次数至少砍半。环境问题的特点是症状离病因很远,一张对照表胜过十次口头支援。

环境的版本化建议

环境搭好之后,最后一步是把"怎么搭的"固化下来。最简的做法是在工程根维护一份环境说明,记录三样:运行时与容器的精确版本号(精确到小数位)、解压或安装的关键参数、本地初始化脚本的执行顺序。更进一步的做法是把环境写进可执行的初始化脚本——新同事 clone 完跑一条命令,运行时下载、容器解压、应用部署、数据初始化一气呵成。两种做法的成本差不了多少,但体验差一个时代:前者靠人照着说明操作,后者靠脚本兜底。青梧书肆选择的是中间态:环境说明加半自动脚本(容器初始化自动化,数据初始化给脚本带开关)。经验是别追求一步到位的全自动——全自动脚本本身的维护也是成本,环境说明加关键脚本,已经能覆盖九成的新人求助。

本节要点回顾

  • 容器版本跟着命名空间走:javax 代码配 Tomcat 9,jakarta 代码配 Tomcat 10 以上,跨代必翻车;
  • 两条铁律撑起目录约定:公开目录直接可达,WEB-INF 容器保护不可直达——这条边界既是部署常识也是安全模型的雏形;
  • 404 与 500 是两种病:前者是地址没对上资源(链路问题),后者是执行出了异常(代码问题),先分辨再动手;
  • 十行的时钟页面是全书的验电器:时间在走证明页面是活的代码,会话号不变预告了第 2 章的会话机制。

环境已就位,老站第一次在你的机器上"活"了。下一章我们把灯全部打开:从你在地址栏敲下回车开始,逐帧回放一次请求在容器内部的完整旅程。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U