基于Maven与Apache服务器的Spring项目页面加载404错误求助
我来帮你一步步排查这个404问题,毕竟部署Spring Boot到外部Tomcat时踩过不少类似的坑~
1. 先确认打包方式与部署包结构
Spring Boot要部署到外部Apache Tomcat,必须打包成war包,默认的jar包是给内置Tomcat用的,直接丢到外部Tomcat肯定出问题。先检查你的pom.xml:
- 确保有
<packaging>war</packaging>,而不是<packaging>jar</packaging>。 - 得排除Spring Boot自带的Tomcat依赖,避免和外部Tomcat冲突:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 还要加Tomcat的servlet-api依赖,范围设为provided,避免打包进去 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>和你的Tomcat版本对应,比如Tomcat 9用9.0.x</version> <scope>provided</scope> </dependency>
另外,打包好的war包要放到Tomcat的webapps目录下,启动Tomcat后会自动解压。访问路径要注意:http://localhost:8080/你的war包名称/控制器映射路径,比如war包叫my-spring-app.war,控制器映射是/landing,那得访问http://localhost:8080/my-spring-app/landing,别直接访问根路径哦,除非你配置了默认跳转。
2. 检查Spring Boot启动类的配置
你的SpringBootApplicationStarter.java必须继承SpringBootServletInitializer,并重写configure方法,这样外部Tomcat才能正确加载Spring应用的上下文:
@SpringBootApplication public class SpringBootApplicationStarter extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootApplicationStarter.class); } public static void main(String[] args) { SpringApplication.run(SpringBootApplicationStarter.class, args); } }
如果你还写了MyWebAppInitializer这个自定义初始化器,要小心它和上面的配置冲突——其实用SpringBootServletInitializer就足够了,除非你有特别复杂的自定义初始化逻辑,不然可以暂时注释掉MyWebAppInitializer试试。
3. 验证Web配置里的视图解析器
WebConfig.java得正确配置视图解析器,不然Spring找不到你的landing.jsp。比如:
@Configuration @EnableWebMvc @ComponentScan(basePackages = "你的控制器所在的包路径,比如com.yourproject.controller") public class WebConfig implements WebMvcConfigurer { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); // 这里要和你的jsp实际路径对应 resolver.setSuffix(".jsp"); return resolver; } // 如果需要访问静态资源(比如css、js),还要加这个配置: @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") .addResourceLocations("/static/"); } }
重点检查landing.jsp的位置:如果prefix是/WEB-INF/views/,那jsp必须放在src/main/webapp/WEB-INF/views/目录下,放在src/main/resources里是不行的——外部Tomcat只会识别webapp目录下的Web资源。
4. 核对控制器的映射路径
看看LandingController.java的映射有没有写错:
@Controller public class LandingController { @GetMapping("/landing") // 或者用@RequestMapping("/landing"),效果一样 public String showLandingPage() { return "landing"; // 这个要和jsp的文件名完全一致,不用带后缀 } }
另外,要确保控制器所在的包被Spring扫描到:要么SpringBootApplicationStarter的@SpringBootApplication默认扫描启动类所在包及子包,要么WebConfig的@ComponentScan明确包含控制器的包路径,不然Spring找不到这个控制器,自然会返回404。
5. 查看Tomcat日志找线索
如果上面的配置都没问题,那就去Tomcat的logs目录翻日志——catalina.out或者localhost.log里会有详细的错误信息:
- 比如有没有显示应用部署失败?有没有类加载异常?
- 有没有“找不到视图landing”的错误?
- 有没有“No mapping found for HTTP request with URI...”的警告?
这些日志能直接帮你定位问题,比如如果日志说找不到映射,那就是控制器没被扫描到或者路径写错了。
6. 确认项目文件结构是否符合规范
标准的Spring Boot war项目结构应该是这样的,你可以对照自己的结构看看:
src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── yourproject/ │ │ ├── SpringBootApplicationStarter.java │ │ ├── config/ │ │ │ ├── RootConfig.java │ │ │ └── WebConfig.java │ │ └── controller/ │ │ └── LandingController.java │ ├── resources/ │ │ ├── application.properties │ │ └── static/ │ └── webapp/ │ ├── WEB-INF/ │ │ ├── views/ │ │ │ └── landing.jsp │ │ └── web.xml (可选,Spring Boot可以不用这个) │ └── index.html (可选) └── pom.xml
如果你的jsp放错了位置,或者webapp目录缺失,都会导致404。
内容的提问来源于stack exchange,提问作者architjn

