Servlet 容器与 Servlet/JSP(零基础详细版)

目标:会在 Tomcat 上编写表单处理 Servlet,理解生命周期与 Filter,使用 JSP 输出并对比 JSON。

← 返回一级入口

学习目标与前置

建议用时:60-90 分钟准备:已安装 JDK、Maven,Tomcat(外置)或 Maven Tomcat 插件

Step 1:创建 Maven Web 项目

mvn archetype:generate ^
  -DgroupId=demo ^
  -DartifactId=servlet-demo ^
  -DarchetypeArtifactId=maven-archetype-webapp ^
  -DinteractiveMode=false
cd servlet-demo

目录要点:src/main/java 写 Servlet/Filter,src/main/webapp 放 JSP 和静态资源,pom.xml 定义依赖与插件。

Step 2:添加 Servlet API 依赖与 Tomcat 插件

<dependencies>
  <dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>5.0.0</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <path>/servlet-demo</path>
        <port>8080</port>
      </configuration>
    </plugin>
  </plugins>
</build>

说明:scope=provided 表示运行时由容器提供;Tomcat 插件方便本地跑。

Tomcat 介绍与工作原理

Tomcat 是 Apache 软件基金会维护的开源 Servlet/JSP 容器,负责解析 HTTP/HTTPS 请求、分发线程、执行 Servlet 代码并返回响应。它提供了 Web Server(连接器)与 Servlet Engine(容器)两部分:前者监听端口接收请求,后者根据 URL 映射把请求交给具体的 Servlet、Filter、JSP。

理解这些概念后,在本地只需把 war 放入 webapps 并启动 Tomcat,即可用浏览器验证 Servlet/JSP 行为,调试和线上部署流程也都会保持一致。

在 IntelliJ IDEA 中使用 Tomcat

  1. 准备工作:确认使用 IntelliJ IDEA Ultimate(社区版没有应用服务器集成功能),并提前下载好独立的 Tomcat。导入或创建 Maven Web 项目后检查 pom.xml 中存在 war 打包配置。
  2. 创建运行配置:依次点击 Run > Edit Configurations > “+” > Tomcat Server > Local,首次创建会提示选择 Tomcat 安装目录(即解压目录)。IDEA 会自动识别 bin、conf 并创建默认配置。
  3. 部署应用:切换到 Deployment 标签,点击 “+” 选择 “Artifact” 或 “war exploded”,一般建议选择 project-name:war exploded 方便热部署;Context path 建议与项目名一致(如 /servlet-demo)。
  4. 调优与调试:在 Server 标签可修改端口、JRE、VM options;在 “Before launch” 中添加 “Build” 或 “Build Artifacts” 确保每次运行前自动编译。点击 Debug 运行即可在 Servlet 的 doGet/doPost 设置断点单步排查。
  5. 验证与热部署:启动后 IDEA 控制台会输出 Tomcat 日志,浏览器访问 http://localhost:8080/servlet-demo 进行验证。修改 JSP 或类后点击 “Update classes and resources” 可热更新,避免频繁重启。

IDEA 对 Tomcat 的一体化支持覆盖了启动、调试、日志查看、热部署和远程部署(可在 Deployment 中配置 SFTP/FTP)。熟练这些操作可以显著缩短“改代码 → 构建 → 启动 → 验证”的迭代周期。

Step 3:编写 Servlet 与 Filter

flowchart LR
  A[浏览器请求] --> B[Filter 日志/鉴权]
  B --> C[Servlet 处理 GET/POST]
  C --> D1[JSON 响应]
  C --> D2[JSP 渲染转发]
// src/main/java/demo/web/TodoServlet.java
@WebServlet("/todos")
public class TodoServlet extends HttpServlet {
  private final List<String> todos = new ArrayList<>();

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    req.setCharacterEncoding("UTF-8");
    String title = req.getParameter("title");
    todos.add(title);
    resp.setContentType("application/json;charset=UTF-8");
    resp.getWriter().write("{\"size\":" + todos.size() + "}");
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setContentType("application/json;charset=UTF-8");
    resp.getWriter().write(new ObjectMapper().writeValueAsString(todos));
  }
}
// src/main/java/demo/web/LogFilter.java
@WebFilter("/*")
public class LogFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest r = (HttpServletRequest) req;
    long t0 = System.nanoTime();
    System.out.println("REQ " + r.getMethod() + " " + r.getRequestURI());
    chain.doFilter(req, res);
    System.out.println("COST " + (System.nanoTime() - t0)/1_000_000 + "ms");
  }
}

Step 4:编写 JSP 对比输出

<%-- src/main/webapp/index.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<body>
  <h3>JSP 渲染 todos</h3>
  <ul>
    <% java.util.List list = (java.util.List) request.getAttribute("todos"); %>
    <% if(list != null) { for(Object t: list){ %>
      <li><%= t %></li>
    <% }} %>
  </ul>
</body>
</html>

对比:JSP 用于服务端渲染;JSON 用于前后端分离,现代项目更常用后者。

Step 5:运行

操作步骤(课堂演示)

  1. POST /todos 新增一条,刷新 GET /todos 查看 JSON 列表。
  2. 在 Filter 中打印耗时,刷新查看日志。
  3. 访问 JSP 页面,展示列表,说明 JSON/前后端分离的优势。

常见问题与排查

课堂练习

课后巩固