踩坑实战分享如何在 IntelliJ IDEA 中创建一个包含 JSP 和 Servlet6.0 的 Maven Web 项目,并配置 Tomcat 进行调试
在现代 Java Web 开发体系中,虽然 Spring Boot 早已成为主流,但 JSP + Servlet 依然是理解 Web 容器原理、请求响应机制、MVC 分层思想的重要基础。对于初学者来说,能够在 IntelliJ IDEA 中从零创建一个包含 JSP 和 Servlet 6.0 的 Maven Web 项目,并成功配置 Tomcat 进行调试,不仅能打通“开发—部署—运行—排错”的完整链路,也能为后续学习 Spring MVC、Spring Boot、微服务架构打下扎实基础。
本文讲解以下内容:如何在 IDEA 中创建 Maven Web 项目、如何引入 Jakarta Servlet 6.0 依赖、如何编写 JSP 与 Servlet、如何配置 Tomcat 10+、如何进行断点调试、如何处理常见报错。文章尽可能覆盖细节,让你照着一步步操作就能跑通项目。
一、准备工作与版本说明
在开始之前,需要先明确一个关键事实:Servlet 6.0 属于 Jakarta EE 10 规范,包名是 jakarta.servlet.*,并不再是旧时代的 javax.servlet.*。因此,Tomcat 版本也要匹配 Jakarta 命名空间。
1. 必备软件
- JDK 17 或更高版本(推荐 JDK 17,稳定且兼容性好)
- IntelliJ IDEA(Community 版也可完成主要操作,Ultimate 更方便)
- Maven 3.8+
- Tomcat 10.1+(非常关键,Tomcat 9 对应 javax,不适配 Servlet 6.0)
2. 版本匹配建议(推荐组合)
- JDK:17
- Maven:3.9.x
- Servlet API:6.0.0
- JSP API:Jakarta JSP 3.1
- Tomcat:10.1.x
- IDEA:2023+ 或 2024+
二、在 IntelliJ IDEA 中创建 Maven Web 项目
下面正式开始创建项目。
1. 新建项目
打开 IDEA,选择:
File → New → Project
在新建页面中选择:
- 左侧:Maven
- JDK:选择本机 JDK 17
- 勾选(如果有)Create from archetype 可以不选,直接空项目更清晰
点击 Next,填写:
- GroupId:com.example
- ArtifactId:jsp-servlet6-demo
- Version:1.0-SNAPSHOT
完成后点击 Finish。
2. 调整项目目录结构为标准 Web 结构
创建并确认如下目录(非常重要):
text
jsp-servlet6-demo ├─ src │ ├─ main │ │ ├─ java │ │ │ └─ com/example/web │ │ ├─ resources │ │ └─ webapp │ │ ├─ WEB-INF │ │ │ └─ web.xml (可选,Servlet 6可用注解替代) │ │ └─ index.jsp │ └─ test │ └─ java └─ pom.xml
如果 src/main/webapp 没有自动出现,可以手动创建。
在 IDEA 中右键目录可标记类型(Mark Directory as),但 Maven 项目通常会自动识别。
三、编写 pom.xml:引入 Servlet 6.0 与 JSP 依赖
下面给出一个可用的 pom.xml 示例。重点是依赖与打包方式:
xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>jsp-servlet6-demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- Servlet 6.0 API,容器提供,故 scope=provided --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <!-- JSP API(通常容器提供,这里用 provided) --> <dependency> <groupId>jakarta.servlet.jsp</groupId> <artifactId>jakarta.servlet.jsp-api</artifactId> <version>3.1.1</version> <scope>provided</scope> </dependency> <!-- JSTL(如果你后续 JSP 要用标签库可加入) --> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> <version>3.0.1</version> </dependency> </dependencies> <build> <finalName>jsp-servlet6-demo</finalName> <plugins> <!-- 编译插件 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> </plugin> <!-- WAR 打包插件 --> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> </plugins> </build> </project>
关键解释
- packaging 必须是 war,因为我们部署到 Tomcat。
- jakarta.servlet-api 必须用 provided,否则会和容器内置版本冲突。
- Servlet 6.0 对应的是 jakarta.* 包名,代码里不能再写 javax.*。
四、编写 Servlet 与 JSP 页面
接下来写最小可运行示例:一个首页 JSP,一个 Servlet。
1. 编写 HelloServlet.java
在 src/main/java/com/example/web/ 下新建:
java
package com.example.web; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; @WebServlet("/hello") public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("name"); if (username == null || username.isBlank()) { username = "Guest"; } req.setAttribute("username", username); req.setAttribute("now", LocalDateTime.now().toString()); // 转发到 JSP 展示 req.getRequestDispatcher("/WEB-INF/views/hello.jsp").forward(req, resp); } }
这里使用了注解 @WebServlet("/hello"),因此可以不写 web.xml 映射。
2. 编写 JSP 页面
在 src/main/webapp/WEB-INF/views/ 下新建 hello.jsp:
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello JSP</title> </head> <body> <h2>Hello, ${username}!</h2> <p>Current Time: ${now}</p> <p>This page is rendered by JSP + Servlet 6.0</p> </body> </html>
再在 src/main/webapp/ 下新建 index.jsp 作为入口页:
jsp
<%@ page contentType="text/html;charset=UTF-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>JSP + Servlet 6.0 Demo</h1> <a href="hello?name=Idea">访问 HelloServlet</a> </body> </html>
五、是否需要 web.xml?两种方式都讲清楚
Servlet 3.0 以后就支持注解配置,Servlet 6.0 同样支持。
所以你可以:
- 方式A(推荐初学者):只用注解 @WebServlet,不写 web.xml
- 方式B(传统方式):使用 web.xml 显式配置 servlet 和映射
如果你想保留 web.xml,可在 WEB-INF/web.xml 写:
xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> <display-name>jsp-servlet6-demo</display-name> </web-app>
注意 schema 与 version 要和 Jakarta EE 10 / Servlet 6.0 对齐。
六、在 IDEA 中配置 Tomcat 进行运行与调试
这是最关键的实操环节。
1. 添加 Tomcat 服务器
菜单进入:
Run → Edit Configurations...
点击左上角 +,选择:
Tomcat Server → Local
在弹窗中设置:
- Name:Tomcat10-jsp-servlet6
- Application server:点击 Configure,选择你本地 Tomcat 10.1 安装目录
- JRE:选择 JDK 17
2. 部署 Artifact
切换到 Deployment 选项卡:
- 点击 +
- 选择 Artifact...
- 选择 jsp-servlet6-demo:war exploded(推荐 exploded,调试更方便)
设置 Application context:
- /jsp-servlet6-demo(可自定义)
3. 启动前构建
在 Before launch 中确保有:
- Build
- Build Artifacts(如有)
这样每次启动会先编译项目。
七、启动项目并访问测试
点击运行(绿色三角)启动 Tomcat。
控制台看到类似日志说明启动成功:
- Server startup in ... ms
- Deploying web application directory ...
浏览器访问:
- 首页
http://localhost:8080/jsp-servlet6-demo/ - Servlet 页面
http://localhost:8080/jsp-servlet6-demo/hello?name=Tomcat
如果你看到 JSP 渲染的用户名和时间,说明项目链路已经跑通。
八、如何在 IDEA 里进行断点调试
调试是学习 Servlet 生命周期和请求流程的最佳方式。
1. 打断点
在 HelloServlet#doGet 内点击行号左侧打红点,例如:
java
String username = req.getParameter("name");
2. Debug 启动
不要点 Run,改点 Debug(小虫子图标)。
访问 /hello?name=debug 后,程序会停在断点处。
3. 常用调试操作
- Step Over(F8):逐行执行
- Step Into(F7):进入方法内部
- Resume Program(F9):继续运行
- Evaluate Expression:临时计算表达式
你可以观察:
- req.getParameter(...) 如何取值
- req.setAttribute(...) 如何传递到 JSP
- forward 与 redirect 的行为差异
九、常见错误与解决方案(高频踩坑)
1. ClassNotFoundException: javax.servlet...
原因:你代码或依赖仍在使用 javax.servlet。
解决:全部改为 jakarta.servlet,并使用 Tomcat 10+。
2. 404 找不到 Servlet
检查顺序:
- URL 是否正确(含 context path)
- @WebServlet("/hello") 路径是否匹配
- Artifact 是否部署成功
- 是否启动的是正确 Tomcat 配置
3. JSP 访问 /WEB-INF/... 404
这是正常的:WEB-INF 下资源不能被浏览器直接访问。
正确方式是通过 Servlet forward 转发进去。
4. 端口冲突(Address already in use)
8080 被占用。
去 Tomcat 配置中改端口,例如 8081,或释放占用端口。
5. 页面中文乱码
确保三处统一 UTF-8:
- JSP contentType="text/html;charset=UTF-8"
- HTML <meta charset="UTF-8">
- IDEA 文件编码 UTF-8
6. Maven 依赖下载慢或失败
可配置国内镜像(如阿里云 Maven 镜像),并检查 IDEA Maven settings 使用的 settings.xml。
十、进阶建议:让项目更接近真实开发
当基础项目跑通后,可以逐步增加以下能力:
- 引入 JSTL 与 EL 完整视图表达
- 增加 Filter(字符编码、登录拦截)
- 增加 Listener(应用启动初始化)
- 引入数据库访问(JDBC / MyBatis)
- 按 MVC 分层(controller/service/dao)
- 统一异常处理与日志框架(Logback)
这些实践会让你从“教学 demo”走向“可维护项目”。
十一、完整流程回顾(速记版)
你可以把本文浓缩成以下 10 步:
- 安装 JDK17、IDEA、Maven、Tomcat10.1
- IDEA 新建 Maven 项目
- pom.xml 设置 packaging=war
- 引入 jakarta.servlet-api:6.0.0(provided)
- 创建 src/main/webapp 与 JSP 页面
- 编写 HelloServlet,使用 jakarta.servlet.*
- (可选)编写 web.xml 6.0 描述
- Run Configurations 添加 Tomcat Local
- Deployment 选择 war exploded
- Run/Debug 启动,浏览器访问并断点调试
在 IntelliJ IDEA 中创建 JSP + Servlet 6.0 的 Maven Web 项目,看似是一个“传统技术栈练习”,但它背后连接的是 Java Web 最根本的运行机制:请求如何进入容器、Servlet 如何处理参数、JSP 如何参与视图渲染、Tomcat 如何管理应用生命周期。
当你真正把这套流程独立跑通并能调试排错时,你对 Java Web 的理解会明显提升。后续无论学习 Spring MVC、Spring Boot,还是理解网关、过滤器、拦截器、会话管理,都会更轻松。
更多推荐

所有评论(0)