SpringBoot 3项目控制器返回404错误,寻求排查帮助
Spring Boot 3 控制器返回404问题排查与解决
问题概述
使用IntelliJ内置向导或spring.io创建的Spring Boot 3.3.5项目(仅含Spring Web依赖),打包为WAR部署到Tomcat 9.4.1后,访问控制器接口返回404。Java版本为17,旧的Spring Boot 2.x项目可正常运行,已尝试修改server.servlet.context-path为/te或空值,均无效。
项目核心配置与代码
POM依赖
<dependencies> <!-- Spring Boot Web Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.3.5</version> </dependency> <!-- Spring Boot Logging --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> <!-- Spring Boot Actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
POM父依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.5</version> <relativePath/> </parent>
application.properties
spring.application.name=te server.servlet.context-path=/te # 已尝试设为空值 server.port=8080
启动类TeApplication
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TeApplication { public static void main(String[] args) { SpringApplication.run(TeApplication.class, args); } }
Servlet初始化类
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(TeApplication.class); } }
控制器类AboutController
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/te") public class AboutController { private static final Logger log = LogManager.getLogger(AboutController.class); @GetMapping(value = "/about") public String aboutMessage() { return "Hello from About!"; } }
问题排查与解决方案
1. 路径匹配错误
当前配置下,实际有效访问路径应为localhost:8080/te/te/about,原因是:
server.servlet.context-path=/te是应用全局上下文路径- 控制器的
@RequestMapping("/te")是控制器级别的路径前缀 - 方法的
@GetMapping("/about")是接口具体路径
若要实现localhost:8080/te/about的访问,需修改控制器注解:
@RestController // 删除或注释@RequestMapping("/te") public class AboutController { @GetMapping(value = "/about") public String aboutMessage() { return "Hello from About!"; } }
2. Tomcat版本不兼容(核心问题)
Spring Boot 3.x基于Jakarta EE 9+规范,而Tomcat 9.x仍使用Java EE 8规范,两者API包名从javax.*改为jakarta.*,直接部署会导致Spring容器无法正确初始化控制器。
解决方法:
- 升级Tomcat到10.1.x及以上版本(推荐10.1.18+,适配Spring Boot 3.3.5)
- 若必须使用Tomcat 9,需添加Jakarta兼容桥接依赖,但不推荐,优先升级Tomcat版本
3. 组件扫描验证
虽然启动类位于控制器上级包,可显式指定扫描包确保控制器被加载:
@SpringBootApplication(scanBasePackages = "你的项目根包路径") // 替换为实际包名,如com.example.te public class TeApplication { // ... }
4. 日志验证控制器加载状态
查看项目启动日志,搜索AboutController或Mapping GET关键字:
- 若未找到相关日志,说明控制器未被Spring容器扫描,需检查:
- 包结构是否正确,启动类是否在控制器的父包或同级包
- 控制器类是否被正确编译到WAR包的
target/classes目录中
内容的提问来源于stack exchange,提问作者Morkus
相关产品推荐
相关产品推荐

