未使用Spring Boot的Spring MVC应用部署Tomcat后出现404错误
问题描述
我想创建一个不使用Spring Boot的简单“Hello World”Spring MVC Web应用并部署到Tomcat。构建WAR包部署到独立Tomcat后,访问http://localhost:8080/simple-spring-mvc/home返回404错误,但catalina.out等日志文件中无任何错误信息。
使用版本
- Tomcat 11
- Spring MVC 6.2.4
项目目录结构
simple-spring-mvc/ ├── pom.xml ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ ├── config/ │ │ │ │ ├── WebAppInitializer.java │ │ │ │ └── WebConfig.java │ │ │ └── controller/ │ │ │ └── HomeController.java │ │ └── webapp/ │ │ └── WEB-INF/ │ │ └── views/ │ │ └── home.jsp
项目代码文件
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>simple-spring-mvc</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <java.version>21</java.version> <spring.version>6.2.4</spring.version> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> <dependencies> <!-- Spring Web MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- JSP API --> <dependency> <groupId>jakarta.servlet.jsp</groupId> <artifactId>jakarta.servlet.jsp-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <!-- JSTL --> <dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>simple-spring-mvc</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> </plugins> </build> </project>
WebAppInitializer.java
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
WebConfig.java
@Configuration @EnableWebMvc @ComponentScan("com.example.controller") public class WebConfig implements WebMvcConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); registry.viewResolver(resolver); } }
HomeController.java
@Controller @RequestMapping("/home") public class HomeController { @GetMapping() public String home(Model model) { model.addAttribute("message", "Hello World!"); return "home"; } }
home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>Spring MVC Demo</title> </head> <body> <h1>${message}</h1> </body> </html>
排查与解决步骤
1. 校验Servlet API包导入正确性
Spring MVC 6.x基于Jakarta EE API,AbstractAnnotationConfigDispatcherServletInitializer的正确包路径是org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer,确保代码中没有误用旧的javax包路径。
2. 确认组件扫描有效性
在HomeController添加构造方法日志,验证Spring是否正确扫描并实例化控制器:
public HomeController() { System.out.println("HomeController 已初始化"); }
若启动Tomcat后未看到该日志,说明@ComponentScan配置的包范围错误,需检查包名是否与实际代码一致。
3. 添加静态资源转发配置
当DispatcherServlet映射为/时,会接管所有请求,需在WebConfig中添加配置,将静态资源请求转发到Tomcat默认Servlet,避免拦截JSP请求:
@Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); }
4. 检查WAR包结构
解压生成的WAR包,确认:
WEB-INF/classes目录下存在编译后的com.example.config和com.example.controller类文件WEB-INF/views/home.jsp文件存在WEB-INF/lib目录包含spring-webmvc、JSTL相关依赖jar包
5. 验证Tomcat部署状态
登录Tomcat管理控制台(默认地址http://localhost:8080/manager/html),查看应用是否处于"running"状态,若部署失败,控制台会直接显示错误原因。
6. 简化视图解析器配置(可选)
将WebConfig中的视图解析器配置简化为以下代码,减少手动配置出错概率:
@Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/views/", ".jsp"); }
内容的提问来源于stack exchange,提问作者Oleksandr Myronets

