Spring REST控制器URL问题:从零构建应用访问出现404错误
嘿,你的控制器代码里的URL映射逻辑本身是对的——@RequestMapping("/api") 加上 @GetMapping("/test"),再配合请求参数messageId,访问http://localhost:8080/api/test?messageId=61 理论上完全没问题。但出现404,大概率是Spring没扫描到这个控制器,或者有一些容易忽略的配置细节出错了。我给你列几个最常见的排查点,你挨个核对下:
1. 先确认控制器是否在Spring的扫描范围内
Spring Boot默认只会自动扫描主应用类(带@SpringBootApplication的那个类)所在包及其子包下的所有组件(包括控制器)。举个例子:如果你的主应用类在com.myapp包下,那你的MyController得放在com.myapp.controller或者com.myapp.api这种子包下才行;要是控制器在com.other这种和主应用类平级甚至外部的包,Spring根本找不到它。
解决办法:
- 最简单的:把控制器移到主应用类的子包下面;
- 要是不想动代码:在主应用类上加上
@ComponentScan(basePackages = "你的控制器所在包路径"),明确告诉Spring要扫描这个包。
2. 核对项目的实际运行端口
你访问的是8080端口,但说不定你的配置文件里改了端口?比如application.properties里写了server.port=8081,那8080端口根本没服务在跑,自然返回404。
怎么确认?看项目启动时的控制台日志,找类似Tomcat started on port(s): 8080 (http)的行,那就是实际运行的端口。
3. 检查依赖是否正确引入
你用了@RestController和@RequestMapping这些Spring Web的注解,得确保项目里已经引入了Spring Web的依赖。如果是Spring Boot项目:
- Maven的话,
pom.xml里要有spring-boot-starter-web依赖; - Gradle的话,
build.gradle里得有对应的implementation 'org.springframework.boot:spring-boot-starter-web'配置。
要是没加这个依赖,Spring根本不会加载Web相关的组件,控制器自然也不会生效。
4. 检查请求路径的拼写细节
虽然你写的路径看起来没问题,但还是要注意:
- 大小写问题:Spring MVC默认是大小写敏感的,比如你控制器里是
/api/test,但访问时写成/API/Test就会404; - 多余斜杠:比如
/api//test这种,虽然Spring一般会处理,但最好避免这种写法,确保路径和控制器里的完全一致。
5. 看看启动日志有没有异常
启动项目时仔细看控制台日志,有没有类似“Failed to instantiate controller”或者控制器加载失败的错误信息。如果有异常,先解决那个异常,控制器才能正常工作。
举个能正常运行的例子参考下:
主应用类(放在com.myapp包):
package com.myapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } }
控制器(放在com.myapp.controller包):
package com.myapp.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class MyController { @GetMapping("/test") public String poll(@RequestParam Long messageId) { return "ok"; } }
按照这个结构配置好,再访问http://localhost:8080/api/test?messageId=61,应该就能正常返回"ok"了。
内容的提问来源于stack exchange,提问作者Denis Stephanov

