Java Web开发入门:从Servlet、JSP到Tomcat部署的完整实战指南

📅 2026/8/10 7:11:24
Java Web开发入门:从Servlet、JSP到Tomcat部署的完整实战指南
很多同学在入门 Java Web 开发时面对 Servlet、JSP、Tomcat 这些概念常常感到无从下手网上资料要么过于陈旧要么零散不成体系。本文将为你梳理一套从零到一的完整学习路径涵盖 JavaEE 核心、Tomcat 服务器、JSP 动态页面以及使用 IDEA 进行项目部署的全流程。无论你是刚学完 Java 基础的新手还是希望系统回顾 Web 开发核心的开发者都能通过本文的实战示例和避坑指南快速搭建起自己的第一个 Web 应用。1. Java Web 开发核心概念与背景在开始动手之前我们需要先理解几个核心概念这能帮助你从宏观上把握 Java Web 开发的全貌而不是盲目地敲代码。1.1 什么是 Java Web 与 JavaEEJava Web通常指使用 Java 技术栈来构建基于浏览器/服务器B/S架构的应用程序。它的核心在于处理 HTTP 请求生成动态的 HTML 内容并返回给客户端浏览器。JavaEE (Java Platform, Enterprise Edition)现在称为 Jakarta EE是 Java 的企业级版本。它提供了一套标准规范如 Servlet、JSP、EJB 等和 API用于开发大规模、分布式、多层结构的企业应用。我们常说的 Java Web 开发其核心技术Servlet, JSP正是 JavaEE 规范的一部分。简单理解Servlet 和 JSP 是 Java Web 的基石它们属于 JavaEE 规范。1.2 核心组件Servlet、JSP 与 TomcatServlet:可以理解为运行在服务器端的 Java 小程序。它不包含主方法main其生命周期由 Web 容器如 Tomcat管理。Servlet 的主要作用是接收和处理 HTTP 请求Request并生成 HTTP 响应Response。它是 Java Web 的控制器Controller负责业务逻辑。JSP (JavaServer Pages):其本质是一个特殊的 Servlet。它允许我们在 HTML 页面中嵌入 Java 代码片段Scriptlet和 JSP 标签从而动态生成网页内容。JSP 更侧重于视图View的呈现。在项目实践中通常使用 JSP 来展示数据而由 Servlet 处理请求和准备数据。Tomcat:一个开源的、轻量级的Web 应用服务器和Servlet 容器。它的核心功能就是解析 HTTP 请求并将其分发给对应的 Servlet 进行处理最后将 Servlet 的响应返回给客户端。没有 Tomcat或其他 Servlet 容器如 Jetty我们编写的 Servlet 就无法运行。1.3 HTTP 协议Web 通信的基石整个 Java Web 交互都建立在 HTTP超文本传输协议之上。你需要理解的基本概念包括请求Request与响应Response一次完整的交互。请求方法GET获取资源、POST提交数据最为常用。状态码200成功、404未找到、500服务器内部错误等。请求头Header与响应头携带元信息如内容类型Content-Type、Cookie 等。会话Session与 Cookie用于在无状态的 HTTP 协议下维持用户状态。理解了这些你就知道了 Servlet 和 JSP 是在为什么样的通信模型而工作。2. 环境准备与版本说明工欲善其事必先利其器。以下是搭建 Java Web 开发环境所需的全部组件。请注意版本号会随时间更新本文以当前2025年常见稳定版本为例重点是掌握配置思路。2.1 基础软件清单Java Development Kit (JDK):作用编译和运行 Java 程序。版本JDK 8、JDK 11 或 JDK 17LTS 长期支持版。企业中使用 JDK 8 的仍非常多学习时选择 JDK 8 或 11 均可。本文示例使用JDK 11。验证安装在命令行输入java -version和javac -version。Apache Tomcat:作用Servlet 容器用于部署和运行 Web 应用。版本Tomcat 9.x 或 10.x。注意Tomcat 10 及以上版本实现了 Jakarta EE 9 规范包名由javax.servlet变更为jakarta.servlet。为减少初学时的兼容性问题建议选择 Tomcat 9.x对应 JavaEE 8。本文使用Tomcat 9.0.85。获取从 Apache 官网下载 “Core” 下的 zip 或 tar.gz 包即可。集成开发环境 (IDE):IntelliJ IDEA Ultimate (推荐):对 Java Web 开发支持非常完善自带 Tomcat 集成部署功能。Eclipse IDE for Enterprise Java Developers:经典选择需要手动配置服务器。本文后续演示将基于IntelliJ IDEA 2024.1社区版Community进行其已包含基础 Web 开发支持。2.2 环境配置关键步骤1. 配置 JAVA_HOME 环境变量这是很多问题的根源。你需要创建一个名为JAVA_HOME的系统变量指向你的 JDK 安装目录例如C:\Program Files\Java\jdk-11。然后在Path变量中添加%JAVA_HOME%\bin。2. 解压与测试 Tomcat将下载的 Tomcat zip 包解压到任意目录如D:\apache-tomcat-9.0.85。进入bin目录。Windows:双击startup.bat。Linux/macOS:在终端执行./startup.sh。 打开浏览器访问http://localhost:8080。如果看到 Tomcat 的欢迎页说明启动成功。关闭则运行shutdown.bat或./shutdown.sh。3. 配置 IDE在 IDEA 中需要让项目识别 Tomcat 库。我们将在创建项目时具体操作。3. 使用 IDEA 创建第一个 Java Web 项目我们将通过一个完整的“用户信息展示”项目来串联所有知识点。功能很简单一个页面提交用户名另一个页面显示欢迎信息。3.1 创建项目与配置模块新建项目打开 IDEA选择New Project。选择模板左侧选择Java Enterprise。确保Project SDK是你安装的 JDK 11。配置服务器在Application Server区域点击New...-Tomcat Server...然后选择你解压的 Tomcat 目录。IDEA 会自动识别。勾选技术在Additional Libraries and Frameworks中务必勾选Web Application。版本选择4.0对应 Servlet 3.1。暂时不要勾选Create web.xml我们使用较新的注解配置方式。你也可以勾选JSP但 IDEA 通常会默认包含。命名项目输入项目名称如FirstJavaWebDemo选择项目位置点击Create。项目创建后IDEA 会自动生成一个标准的企业级项目结构这是理解后续内容的关键。3.2 理解标准项目结构你的项目目录应该类似如下结构使用“Project”视图查看FirstJavaWebDemo ├── .idea/ # IDEA 配置文件 ├── src/ # 源代码目录 │ └── main/ │ ├── java/ # Java 源代码 (Servlet 放在这里) │ ├── resources/ # 资源文件 (配置文件等) │ └── webapp/ # **Web 应用根目录相当于网站的根路径** │ ├── WEB-INF/ # 受保护目录浏览器无法直接访问 │ │ └── web.xml # Web 部署描述符 (可选我们用注解) │ └── index.jsp # 默认欢迎页面 ├── target/ # 编译输出目录 (由 Maven/Gradle 管理纯 Web 项目可能没有) └── pom.xml # Maven 配置文件 (如果创建时选择了 Maven)核心目录说明src/main/java: 所有 Servlet 和普通 Java 类都放在这里及其子包下。src/main/webapp: 这是最重要的目录所有 HTML、JSP、CSS、JS、图片等前端资源都直接放在这里或它的子目录下。WEB-INF目录下的内容如web.xml、lib库受保护。4. 编写第一个 ServletServlet 3.0 之后我们可以使用WebServlet注解来配置 Servlet无需在web.xml中声明更加简洁。4.1 创建 Servlet 类在src/main/java下新建一个包例如com.example.web。在该包下新建一个 Java 类命名为HelloServlet。编写如下代码// 文件路径src/main/java/com/example/web/HelloServlet.java package com.example.web; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * 使用 WebServlet 注解配置 Servlet * name: Servlet 名称 * urlPatterns: 映射的 URL 路径。当用户访问 /hello 时此 Servlet 被调用。 */ WebServlet(name HelloServlet, urlPatterns /hello) public class HelloServlet extends HttpServlet { /** * 处理 GET 请求 */ Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应内容类型为 HTML编码为 UTF-8解决中文乱码 response.setContentType(text/html;charsetUTF-8); // 获取响应的输出流用于向浏览器输出内容 PrintWriter out response.getWriter(); out.println(!DOCTYPE html); out.println(html); out.println(headtitle第一个Servlet/title/head); out.println(body); out.println(h1Hello, World! 来自 Servlet 的问候。/h1); out.println(p当前时间 new java.util.Date() /p); out.println(/body); out.println(/html); } /** * 处理 POST 请求 (本例暂未使用) */ Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); // 简单处理调用 doGet } }代码解析extends HttpServlet: 必须继承这个类。WebServlet(“/hello”): 这是关键它将该 Servlet 映射到/hello这个 URL 路径。doGet方法当浏览器以 GET 方式请求/hello时自动调用此方法。HttpServletRequest: 封装了所有请求信息参数、头、会话等。HttpServletResponse: 用于构建返回给浏览器的响应。response.setContentType(“text/html;charsetUTF-8”):至关重要设置响应编码避免中文乱码。PrintWriter out response.getWriter(): 获取输出流直接写 HTML 内容。4.2 部署并运行在 IDEA 右上角点击Add Configuration...。点击选择Tomcat Server-Local。在Deployment选项卡点击-Artifact选择你的项目生成的工件通常以:war exploded结尾。这表示部署一个解压的 WAR 包支持热更新。Application context可以设置为/根路径或/demo。设为/则通过http://localhost:8080/hello访问设为/demo则通过http://localhost:8080/demo/hello访问。点击OK保存配置然后点击绿色的运行按钮。IDEA 会自动启动 Tomcat 并部署你的应用。打开浏览器访问http://localhost:8080/hello。你将看到 Servlet 输出的 HTML 页面。恭喜你已经成功创建并运行了第一个 Servlet。5. 编写 JSP 页面与 Servlet 交互单纯用 Servlet 输出 HTML 非常繁琐。接下来我们创建 JSP 作为视图Servlet 作为控制器处理数据。5.1 创建输入页面 (index.jsp)我们将webapp下的index.jsp改造成一个表单提交页面。%-- 文件路径src/main/webapp/index.jsp --% % page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 % !DOCTYPE html html head title用户信息提交/title /head body h2请输入您的信息/h2 %-- 表单提交到 /showInfo 这个 URL对应我们将要创建的 Servlet --% form actionshowInfo methodpost label forusername用户名/label input typetext idusername nameusername requiredbrbr label forage年龄/label input typenumber idage nameage requiredbrbr input typesubmit value提交 /form /body /html5.2 创建处理数据的 Servlet (ShowInfoServlet)这个 Servlet 负责接收表单数据处理后将数据传递给 JSP 页面进行展示。// 文件路径src/main/java/com/example/web/ShowInfoServlet.java package com.example.web; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; WebServlet(/showInfo) public class ShowInfoServlet extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 解决 POST 请求中文参数乱码 request.setCharacterEncoding(UTF-8); // 2. 获取表单参数 String username request.getParameter(username); String ageStr request.getParameter(age); int age Integer.parseInt(ageStr); // 简单转换实际需做异常处理 // 3. (可选) 进行一些业务逻辑处理 String greeting 您好, username !; String ageGroup (age 18) ? 成年人 : 未成年人; // 4. 将数据存入请求作用域 (request scope)传递给 JSP request.setAttribute(greeting, greeting); request.setAttribute(ageGroup, ageGroup); request.setAttribute(userAge, age); // 5. 请求转发到 display.jsp 页面 request.getRequestDispatcher(/display.jsp).forward(request, response); } }关键点解析request.setCharacterEncoding(“UTF-8”):解决 POST 请求体中文乱码必须在获取参数前调用。request.getParameter(“name”): 获取表单中name”username”的输入框的值。request.setAttribute(“key”, value): 将数据存入请求作用域。这些数据可以在本次请求转发的目标页面JSP中取出。request.getRequestDispatcher(“/display.jsp”).forward(request, response):请求转发。服务器内部将请求和响应对象传递给/display.jsp由 JSP 生成最终响应。浏览器地址栏不会改变。5.3 创建展示页面 (display.jsp)这个 JSP 页面负责从请求作用域中取出数据并展示。%-- 文件路径src/main/webapp/display.jsp --% % page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 % !DOCTYPE html html head title用户信息展示/title /head body h1用户信息/h1 %-- 使用 JSP 表达式 (EL) 从请求作用域获取数据 --% pstrong问候语/strong ${greeting}/p pstrong年龄/strong ${userAge} 岁/p pstrong年龄段/strong ${ageGroup}/p hr a hrefindex.jsp返回首页/a %-- 传统的 JSP Scriptlet 写法 (不推荐仅作了解) --% % // 你也可以用 Java 代码块获取 // String g (String) request.getAttribute(greeting); // out.println(p另一种方式 g /p); % /body /html关键点解析${greeting}: 这是JSP 表达式语言 (EL)它自动从pageContext,request,session,application四个作用域中查找名为greeting的属性。简洁且安全避免了 Java 代码嵌入。% … %: 这是JSP Scriptlet里面可以写任意 Java 代码。但在现代开发中强烈不推荐在 JSP 中写大量 Java 代码这会导致视图和逻辑混杂难以维护。应使用 EL 和 JSTL 标签。5.4 运行测试重启 Tomcat 或等待 IDEA 热部署如果配置了。访问http://localhost:8080/(默认会打开 index.jsp)。在表单中输入信息并提交。页面会跳转到display.jsp并显示你输入的信息。至此你已经实现了一个完整的MVC 雏形M (Model 模型):数据username, age通常由 JavaBean 类承载。V (View 视图):display.jsp负责展示。C (Controller 控制器):ShowInfoServlet负责接收请求、处理数据、选择视图。6. 深入理解Servlet 生命周期与核心对象6.1 Servlet 生命周期Servlet 生命周期由容器管理包括三个阶段初始化 (init):当 Servlet 第一次被请求时容器调用init()方法。该方法只执行一次用于加载资源。服务 (service):对于每次请求容器会调用service()方法。service()方法会根据请求类型GET, POST等自动调用对应的doGet(),doPost()等方法。销毁 (destroy):当容器关闭或应用被卸载时调用destroy()方法用于释放资源。6.2 四大作用域对象在 JSP/Servlet 中数据可以在不同范围共享共有四个作用域Page Scope (页面作用域):pageContext仅在当前 JSP 页面内有效。Request Scope (请求作用域):HttpServletRequest在一次完整的请求链中有效包括转发forward不包括重定向redirect。最常用。Session Scope (会话作用域):HttpSession在一次用户会话中有效浏览器不关闭或会话未超时。用于保存用户登录信息等。Application Scope (应用作用域):ServletContext在整个 Web 应用运行期间有效所有用户共享。用于保存全局配置或缓存。选择原则能用小作用域就不用大作用域避免不必要的内存占用和线程安全问题。7. 常见问题与排查思路 (FAQ)在开发过程中你几乎一定会遇到下面这些问题。问题现象可能原因排查与解决思路访问 404 错误1. URL 路径错误。2. Servlet 未正确映射。3. 项目未成功部署。1. 检查浏览器地址栏 URL 是否与WebServlet或web.xml中的映射一致。2. 在 IDEA 的Services工具窗口确认 Tomcat 下你的应用已启动且Application context正确。3. 检查target或out目录下是否有编译好的类文件。中文乱码1. 页面编码未设置。2. 请求/响应编码未设置。3. Tomcat 服务器编码问题。三位一体解决法1.JSP页面确保% page pageEncoding”UTF-8″ %和meta charset”UTF-8″。2.Servlet 响应response.setContentType(“text/html;charsetUTF-8”)。3.Servlet 请求 (POST)request.setCharacterEncoding(“UTF-8”)。4.GET 请求参数修改 Tomcatconf/server.xml中 Connector 标签添加URIEncoding”UTF-8″。Tomcat 启动失败端口被占用8080 端口被其他程序如另一个 Tomcat 实例、Skype 等占用。1. 命令行执行netstat -ano | findstr :8080查找占用进程的 PID。2. 在任务管理器中结束该进程或修改 Tomcat 端口编辑conf/server.xml找到Connector port”8080″ …修改port值。ClassNotFoundException 或 NoClassDefFoundError缺少必要的 Servlet API Jar 包。1. 确保项目依赖了servlet-api.jar。在纯 Web 项目中Tomcat 的lib目录下有这个 jar但编译时需要。在 IDEA 中创建项目时选择Java Enterprise会自动添加依赖。2. 如果使用 Maven在pom.xml中添加依赖注意 scope 为provided因为 Tomcat 运行时已提供。JSP 页面被直接显示源代码Tomcat 未正确识别或编译 JSP。1. 检查 JSP 文件是否放在webapp或其子目录下不能放在WEB-INF下除非通过 Servlet 转发访问。2. 检查 Tomcat 的conf/web.xml中是否注册了JspServlet默认是有的。3. 可能是文件编码异常尝试用记事本另存为 UTF-8 格式。无法跳转到 JSP 页面或跳转后数据丢失混淆了转发 (forward)和重定向 (redirect)。转发 (forward):request.getRequestDispatcher(“url”).forward(req, resp);服务器内部跳转共享 request 作用域地址栏不变。重定向 (sendRedirect):response.sendRedirect(“url”);告诉浏览器去请求新地址不共享 request 作用域地址栏改变。根据需求选择。8. 项目部署与打包 (WAR 文件)开发完成后我们需要将项目部署到独立的 Tomcat 服务器上。8.1 使用 IDEA 打包 WAR点击 IDEA 菜单Build-Build Artifacts…-Build。如果你的项目是 Maven 项目更简单在右侧 Maven 工具窗口执行Lifecycle-package。打包后的 WAR 文件会在target目录下生成。8.2 手动部署到 Tomcat将生成的YourProjectName.war文件复制到 Tomcat 的webapps目录下。启动 Tomcat (bin/startup.bat)。Tomcat 会自动解压 WAR 包并部署应用。访问地址为http://服务器IP:端口/YourProjectName/。其中YourProjectName是 WAR 包的文件名不含.war后缀。8.3 生产环境注意事项关闭管理界面删除webapps目录下的manager,host-manager,docs,examples等文件夹减少安全风险。修改默认端口将server.xml中的8080改为80HTTP或443HTTPS。配置内存参数在bin/catalina.sh(Linux) 或bin/catalina.bat(Windows) 中设置JAVA_OPTS例如-Xms512m -Xmx1024m以防内存溢出。日志管理关注logs目录下的catalina.out,localhost.log等日志文件。使用反向代理生产环境通常在前端使用 Nginx 或 Apache 作为反向代理将请求转发给后端的 Tomcat 集群实现负载均衡和静态资源分离。9. 学习路线与进阶方向掌握了以上内容你已经成功入门 Java Web 开发。接下来可以沿着以下路径深入学习巩固基础JSP 标签库 (JSTL):学习c:forEach,c:if等核心标签彻底告别 JSP 中的 Java 代码。过滤器 (Filter):实现统一编码过滤、权限验证、日志记录。监听器 (Listener):监听应用启动、会话创建等事件。数据库集成学习JDBC掌握如何在 Servlet 中连接数据库如 MySQL。使用数据库连接池如HikariCP,Druid管理连接提升性能。转向现代框架 (必学):Maven/Gradle:项目构建和依赖管理工具。Spring Framework:学习 IoC控制反转和 AOP面向切面编程。Spring MVC:替代原生的 Servlet/JSP提供更强大、更规范的 MVC 框架。MyBatis / Spring Data JPA:优秀的持久层框架简化数据库操作。Spring Boot:约定大于配置快速创建独立、生产级的 Spring 应用。这是当前企业开发的主流。前端技术学习基本的HTML5, CSS3, JavaScript (ES6)。掌握一个前端框架如Vue.js或React实现前后端分离开发。工程化与部署Git:版本控制。Linux:基本的服务器操作命令。Docker:容器化部署。Java Web 的世界广阔而深邃从基础的 Servlet/JSP 到庞大的 Spring 生态每一步都充满了挑战与乐趣。记住最好的学习方式是动手实践。尝试用今天学到的知识做一个简单的留言板、博客系统或者个人记账本在项目中遇到问题、解决问题你的能力会得到最快的提升。如果在实践中遇到任何问题欢迎在评论区交流探讨。