Servlet访问出现404错误求助(IntelliJ+Tomcat9+Maven+Servlet5)
环境:IntelliJ IDEA、Tomcat 9、Maven、Servlet 5
主页可正常访问,但两个测试Servlet均返回404错误。两个Servlet分别为:一个仅用@WebServlet注解未在web.xml映射,另一个同时配置注解和xml映射,均无法访问。
错误信息
HTTP Status 404 – Não Encontrado
Type Status ReportDescription The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Apache Tomcat/9.0.84
相关代码
Servlet 1(HelloServlet)
package br.com.caelum.fj21agenda; import java.io.*; import jakarta.servlet.ServletException; import jakarta.servlet.http.*; import jakarta.servlet.annotation.*; @WebServlet("/servlet") public class HelloServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); //Escreve o texto out.println("<html>"); out.println("<body>"); out.println("Primeira Servlet ^^ yay"); out.println("</body>"); out.println("</html>"); } }
Servlet 2(HelloServlet2)
package br.com.caelum.fj21agenda; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; import jakarta.servlet.annotation.WebServlet; @WebServlet("/hello") public class HelloServlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Preprocess request: we actually don't need to do any business stuff, so just display JSP. request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Postprocess request: gather and validate submitted data and display the result in the same JSP. // Prepare messages. Map<String, String> messages = new HashMap<>(); request.setAttribute("messages", messages); // Get and validate name. String name = request.getParameter("name"); if (name == null || name.trim().isEmpty()) { messages.put("name", "Please enter name"); } else if (!name.matches("\\p{Alnum}+")) { messages.put("name", "Please enter alphanumeric characters only"); } // Get and validate age. String age = request.getParameter("age"); if (age == null || age.trim().isEmpty()) { messages.put("age", "Please enter age"); } else if (!age.matches("\\d+")) { messages.put("age", "Please enter digits only"); } // No validation errors? Do the business job! if (messages.isEmpty()) { messages.put("success", String.format("Hello, your name is %s and your age is %s!", name, age)); } request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response); } }
web.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_5_0.xsd" version="5.0"> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>br.com.caelum.fj21agenda.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/servlet</url-pattern> </servlet-mapping> </web-app>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Projeto Fj21-agenda </title> </head> <body> <h1>Primeira Pagina YAYY</h1> </body> </html>
文件结构说明
项目遵循Maven标准结构:
- Servlet类位于
src/main/java/br/com/caelum/fj21agenda目录下 - Web资源位于
src/main/webapp目录下,包含index.html和WEB-INF目录
排查与解决步骤
版本兼容性修复
Servlet 5属于Jakarta EE 9规范,使用jakarta.servlet包;而Tomcat 9仅支持到Servlet 4(Java EE 8),对应javax.servlet包,这是核心冲突点。- 方案1:降级Servlet依赖到4.x,将代码中
jakarta.servlet替换为javax.servlet,web.xml改用Servlet 4.0的schema - 方案2:升级Tomcat到10.x及以上版本,适配Jakarta EE 9+规范
- 方案1:降级Servlet依赖到4.x,将代码中
确认注解扫描状态
检查web.xml中是否存在<metadata-complete="true">属性,该属性会关闭注解自动扫描,若存在则删除。Servlet 3+默认开启注解扫描,无需额外配置。修正Maven依赖范围
Servlet API依赖需设置为provided,避免打包到war包中与Tomcat自带API冲突:<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency>验证访问路径
访问Servlet时需加上项目上下文路径,例如项目部署上下文为/fj21agenda,则正确访问地址为:http://localhost:8080/fj21agenda/servlethttp://localhost:8080/fj21agenda/hello
检查IDEA部署配置
在IntelliJ IDEA的Run/Debug配置中,确认Tomcat的Deployment选项里:- 项目已添加到部署列表
- Application context设置与访问路径匹配
清理重建项目
执行Maven命令clean和package,清理编译缓存后重新部署到Tomcat,排除编译或打包异常。
内容的提问来源于stack exchange,提问作者SchattenRaff

