
Spring Boot 应用返回 404 通常是因为控制器类未被组件扫描发现,根本原因多为包结构不规范——主启动类与 @RestController 不在同一或子包下,导致 Spring 无法自动注册请求映射。
spring boot 应用返回 404 通常是因为控制器类未被组件扫描发现,根本原因多为包结构不规范——主启动类与 `@restcontroller` 不在同一或子包下,导致 spring 无法自动注册请求映射。
在 Spring Boot 中,@SpringBootApplication 注解默认启用组件扫描(component scan),但仅扫描主启动类所在包及其所有子包。若你的 PhotoController 位于顶层包(如 src/main/java/PhotoController.java)或与 DemoApplication 类不在同一根包下(例如 DemoApplication 在 com.example.demo,而 PhotoController 却在 com.example 或 org.example.api),Spring 将完全忽略该控制器,导致 /api/photos 路径无任何处理器,最终返回 HTTP 404。
✅ 正确的包结构应如下:
src/main/java/
└── com.example.demo/ ← 主启动类所在包(必须)
├── DemoApplication.java ← 含 @SpringBootApplication
├── controller/ ← 推荐子包
│ └── PhotoController.java ← @RestController 必须在此包或其子包内
├── model/
└── service/你当前的项目结构(如截图所示)很可能将 PhotoController 放在了 com.example.demo 外部(例如直接放在 src/main/java/ 下,或独立于 com.example.demo 的其他包中),这会导致 Spring Boot 启动时无法扫描到该控制器。
? 验证与修复步骤:
-
确认主启动类位置:
检查 DemoApplication.java 的包声明,例如:package com.example.demo; // ✅ 必须是此包或其子包
-
将控制器移入正确包路径:
修改 PhotoController.java 的包声明,并调整文件位置:package com.example.demo.controller; // ✅ 与 DemoApplication 同根包 import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PhotoController { @GetMapping(path = "/api/photos", produces = "application/json") public String getAll() { return "finito"; } } -
(可选)显式配置扫描路径(不推荐,仅作调试):
若因历史原因无法调整包结构,可在 @SpringBootApplication 中强制指定扫描范围(但违背约定优于配置原则):@SpringBootApplication(scanBasePackages = {"com.example.demo", "com.example.api"}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
⚠️ 注意事项:
- spring-boot-starter-web 已正确引入(你已在 pom.xml 中声明),无需额外配置;
- application.properties 中的 JPA 和 MySQL 配置与 REST 接口无关,不影响 404 问题,但建议关闭 debug=true 上线前;
- 使用 Postman 测试时,请确保访问 URL 为 http://localhost:8080/api/photos(默认端口 8080),且应用已成功启动(控制台输出含 Tomcat started on port(s): 8080);
- 启动日志中搜索 Mapped "{[/api/photos]}",若未出现该行,说明映射未注册——即扫描失败的明确证据。
✅ 最终验证:重启应用后,控制台应打印类似日志:
Mapped "GET /api/photos" onto public java.lang.String com.example.demo.controller.PhotoController.getAll()
此时再通过 Postman 访问 GET http://localhost:8080/api/photos,即可获得 "finito" 响应。
总结:Spring Boot 的“约定大于配置”原则对包结构有严格要求。确保所有 @Component、@Service、@RestController 等注解类均位于 @SpringBootApplication 类所在包或其子包内,是避免 404 的最根本、最可靠方案。


















