新手向:SpringBoot后端查询到数据,前端404?(附联调时各传参方式注解总结-带你一文搞定联调参数)
前言:
在 Spring Boot 项目开发中,后端小伙伴可能经常遇到这样诡异的场景:
- 后台日志显示查询到了数据,但前端却一脸懵逼地告诉你 404 Not Found?
- 接口明明写好了,Postman 直接访问却提示找不到?
- 调试半天,最后发现只是一个传参方式的问题?🙃
为什么会出现这种情况?是 后端接口定义的问题,还是 前端请求方式不对?或者是 Spring Boot 机制在悄悄“帮忙”,让空数据变成了 404?
这篇文章将带你 快速排查这个经典问题,并且 总结常见的 Spring Boot 传参方式及注解用法,助你在 联调时一次搞定参数对接,不再踩坑!🔥
复刻场景:请问你能找出问题吗?(答案在文末哦)
后端打印出查询结果但测试却是404?你能找出问题所在吗(注意这里不是端口的问题哦,作者配置的启动端口就是8888)


讲到这里了,作者就不妨来先讲讲各类注解在传参的时候的用法
传参注解的使用大全
在 Spring Boot 开发中,前后端交互时,数据的传递方式有多种形式,主要包括 GET、POST、PUT、DELETE 等 HTTP 方法,以及 Query 参数、Path 变量、RequestBody、Header、Form 表单,对应的注解也有不同的用法。
🟢 1. Query 参数(@RequestParam)
适用场景:一般用于 GET 请求,将参数拼接在 URL 后面,如 ?key=value
示例
GET /user/getUserByName?name=Tom
@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/getUserByName")public String getUserByName(@RequestParam String name) {return "查询用户:" + name;}// @RequestParam 可以提供默认值和非必传参数@GetMapping("/getUserByAge")public String getUserByAge(@RequestParam(required = false, defaultValue = "18") int age) {return "用户年龄:" + age;}
}
特点
- 适用于 简单参数传递,如
?key=value形式 - 可以设置
required = false使参数可选 - 可以设置
defaultValue以提供默认值
🔵 2. Path 变量(@PathVariable)
适用场景:用于 RESTful 风格 API,参数作为 URL 路径的一部分,如 /user/1001
示例
前端请求
GET /user/1001
@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/{id}")public String getUserById(@PathVariable("id") Long id) {return "查询用户 ID:" + id;}
}
特点
- 适用于 RESTful 结构,更加语义化
- 需要在
@GetMapping("/{id}")的路径中声明参数 @PathVariable("id")可以省略("id"),但建议保持一致,增强可读性
🟠 3. RequestBody 方式(@RequestBody)
适用场景:用于 POST/PUT 请求,前端传递 JSON 格式的数据,适合 复杂对象
示例
前端请求(JSON-前后端交互的一种数据格式)
{"id": 1001,"name": "Tom","age": 25
}
@RestController
@RequestMapping("/user")
public class UserController {@PostMapping("/add")public String addUser(@RequestBody User user) {return "添加用户:" + user.getName();}
}
特点
- 适用于 复杂数据传输(JSON)
- 需要
@RequestBody注解将 JSON 解析为Java对象 - 默认情况下,Spring Boot 需要使用
@RequestBody来解析 JSON 数据,否则会报 415 错误(Unsupported Media Type) - 需要前端设置
Content-Type: application/json
🟣 4. Form 表单数据(@RequestParam 或 @ModelAttribute)
适用场景:前端以 x-www-form-urlencoded 形式提交数据
示例
前端请求
POST /user/register
Content-Type: application/x-www-form-urlencodedname=Tom&age=25
@PostMapping("/register")
public String registerUser(@RequestParam String name, @RequestParam int age) {return "注册用户:" + name + ",年龄:" + age;
}
或者使用 @ModelAttribute,支持对象自动封装:
@PostMapping("/registerUser")
public String registerUser(@ModelAttribute User user) {return "注册用户:" + user.getName() + ",年龄:" + user.getAge();
}
特点
- 适用于 表单提交
@RequestParam适合单个参数,@ModelAttribute适合对象- 前端需使用
application/x-www-form-urlencoded
🟡 5. Header 方式(@RequestHeader)
适用场景:用于 传递 Token、API Key、User-Agent 等请求头信息
示例
前端请求
GET /user/info
Authorization: Bearer abc123
@GetMapping("/info")
public String getUserInfo(@RequestHeader("Authorization") String token) {return "获取用户信息,Token:" + token;
}
特点
- 适用于 认证信息、请求头参数
@RequestHeader用于获取指定请求头的值
🟠 6. 多参数组合(混合使用-少见)
有时候,我们需要同时接收 路径参数 + Query 参数 + Body 参数,可以 混合使用 多种方式:
@PostMapping("/update/{id}")
public String updateUser(@PathVariable("id") Long id,@RequestParam("role") String role,@RequestBody User user
) {return "更新用户 ID:" + id + ",角色:" + role + ",姓名:" + user.getName();
}
示例请求
POST /user/update/1001?role=admin
Content-Type: application/json{"name": "Tom","age": 26
}
✅ 总结
| 参数类型 | 方式 | 适用场景 | 主要注解 |
|---|---|---|---|
| Query 参数 | ?name=Tom | GET 请求参数 | @RequestParam |
| Path 变量 | /user/1001 | RESTful 风格 | @PathVariable |
| JSON 请求体 | {"name":"Tom","age":25} | POST/PUT 请求 | @RequestBody |
| 表单提交 | name=Tom&age=25 | POST 表单提交 | @RequestParam / @ModelAttribute |
| 请求头 | Authorization: Bearer token123 | 传递 Token / API Key | @RequestHeader |
传参时各类可能会出现问题的解决方案(如果出现了问题,请从下面的几个思路逐步检查!!)
✅ 1. 接口 URL 配置错误
/user/findbyid
检查你的 Controller 是否正确定义了路径。例如:
@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/findById")public User findById(@RequestParam Long id) {// 这里是正常的查询逻辑return userService.getById(id);}
}
可能的问题
- 大小写敏感:你的请求路径是
/user/findbyid,但方法是@GetMapping("/findById"),F 大写,B 大写,URL 访问是大小写敏感的,应该确保前端请求路径与后端路径完全一致。 - 路径拼写错误:检查是否手误拼错,比如
/findbyidvs/findById - 浏览器缓存问题:如果之前请求 404,可能是缓存问题,清理浏览器缓存或使用 Postman、cURL 重新测试。(这个着重注意:edge浏览器有时会出现这个问题!记得点开历史记录清除缓存)
✅ 解决方案 试试访问:
http://localhost:8080/user/findById?id=1
✅ 2. HTTP 方法错误
你的接口是 @GetMapping("/findById"),但如果前端用的是 POST 请求,那么就会返回 404 Not Found。
检查前端请求方式
GET /user/findbyid?id=1
如果前端使用了 POST,但后端是 @GetMapping,就会导致 405
✅ 解决方案
- 如果前端要用
POST,后端应该改为
@PostMapping("/findById")
public User findById(@RequestParam Long id) {return userService.getById(id);
}
- 如果后端是
@GetMapping,前端应该用 GET 请求。
✅ 3. 方法返回值不符合 REST 规范
如果你的 findById 方法返回的是 null,Spring Boot 可能会返回 404 Not Found,而不是 null 值。
检查你的返回值
@GetMapping("/findById")
public User findById(@RequestParam Long id) {User user = userService.getById(id);System.out.println("查询到的用户:" + user);return user; // 如果 user 是 null,Spring Boot 可能会返回 404
}
解决方案
如果希望即使数据为空也返回 200 而不是 404,可以这样:
@GetMapping("/findById")
public ResponseEntity<?> findById(@RequestParam Long id) {User user = userService.getById(id);if (user == null) {return ResponseEntity.ok("用户不存在");}return ResponseEntity.ok(user);
}
✅ 4. 返回数据未被 Spring Boot 识别
Spring Boot 需要 @RestController 或 @ResponseBody 才能正确返回 JSON。
@Controller // ❌ 可能只是普通 Controller,而非 REST
@RequestMapping("/user")
public class UserController {@GetMapping("/findById")public User findById(@RequestParam Long id) {return userService.getById(id);}
}
如果没有 @ResponseBody,Spring 可能会尝试解析为视图,而不是 JSON。
✅ 解决方案
- 确保使用
@RestController(等价于@Controller + @ResponseBody)
@RestController
@RequestMapping("/user")
public class UserController {
如果必须使用 @Controller,那么应该添加 @ResponseBody:
@Controller
@RequestMapping("/user")
public class UserController {@GetMapping("/findById")@ResponseBodypublic User findById(@RequestParam Long id) {return userService.getById(id);}
}
✅ 5. 路由冲突或 Spring Boot 过滤器拦截
Spring Boot 可能有 全局拦截器、过滤器,或者其他 Controller 处理了相同路径的请求,导致你的请求被拦截或返回 404。
解决方案
-
检查
application.properties是否有拦截器
2.查看是否有 ControllerAdvice 处理全局异常
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(NoHandlerFoundException.class)public ResponseEntity<String> handleNotFound() {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("接口不存在");}
}
✅ 6. Spring Boot 404 相关全局配置
在 application.properties 中,检查是否配置了:
server.error.include-message=always
server.error.whitelabel.enabled=false
如果 whitelabel.enabled=true 可能会导致 Spring 自定义错误页面返回 404。
🛠 总结 & 解决方案
| 可能原因 | 解决方案 |
|---|---|
| 大小写敏感 | /findById ≠ /findbyid,保持大小写一致 |
| HTTP 方法错误 | @GetMapping("/findById") 不能用 POST 访问 |
| 返回 null 导致 404 | 使用 ResponseEntity.ok() 处理 |
缺少 @RestController | 使用 @RestController 或 @ResponseBody |
| 路由冲突 | 确保 /user/findById 不是被其他 Controller 拦截 |
| 拦截器或过滤器 | 检查 application.properties 及 ControllerAdvice |
你找到第一部分的bug所在之处了吗?(解答)
答对发在评论区的小伙伴有奖励哦----正确答案就是在解决问题的第四步方案!你发现了吗?-我们只需要把@Controller注解改成@RestController即可
因为我们返回的是一个UserVO对象,复杂类型要解析成json数据给前端交互,如果只用@Controller则会解析为视图对象,但是在前后端分离的项目中基本不用它
修复结果如下:


最后的话:查 Bug 有套路,调接口不迷路!🚀
如果你看到这里,相信你已经对 Spring Boot 接口 404 问题 有了更清晰的认识,同时也掌握了 各种参数传递方式及注解用法。
开发过程中,前后端联调 总会遇到各种坑,但只要掌握排查思路,就能快速定位问题,精准修复 Bug!💪
如果这篇文章对你有帮助,记得点赞 👍、收藏 ⭐、分享 📢,让更多小伙伴少踩坑!也欢迎关注我,后续会持续分享更多 Spring Boot 开发技巧、Bug 查杀指南和最佳实践,让我们一起进步!🚀🔥
👇 你遇到过哪些诡异的接口问题?欢迎评论区交流! 💬
相关文章:
新手向:SpringBoot后端查询到数据,前端404?(附联调时各传参方式注解总结-带你一文搞定联调参数)
前言: 在 Spring Boot 项目开发中,后端小伙伴可能经常遇到这样诡异的场景: 后台日志显示查询到了数据,但前端却一脸懵逼地告诉你 404 Not Found?接口明明写好了,Postman 直接访问却提示找不到?…...
Mysql各操作系统安装全详情
" 至高无上的命运啊~ " MySQL是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的RDBMS (Relational Database Mana…...
RadASM环境,win32汇编入门教程之七
;运行效果 ;RadASM环境,win32汇编入门教程之七 ;在上一个教程里面,我们学习如何把数据显示出来。但是感觉太丑了,在这一教程里,我们来学习一下怎样让它们变漂亮点。 ;主要的内容是如何创建字体,设置字体的大小…...
STL之string类的模拟实现
目录 1. string的成员变量 2. string的成员函数 2.1 string类的c_str()和swap()函数 2.2 string类的构造 2.3 string类的拷贝构造 2.3.1传统写法: 2.3.2现代写法: 2.4string类的运算符重载 2.4.1传统写法: 2.4.2现代写法 2. 5 …...
定期自动统计大表执行情况
一、创建用户并赋权 create user dbtj identified by oracle default tablespace OGGTBS;grant connect,resource to dbtj;grant select any dictionary to dbtj;grant create job to dbtj;grant manage scheduler to dbtj; 二、创建存储表 1、连接到新建用户 conn dbtj/or…...
学习next.js的同时的一些英语单词记录
skip :跳过 optional:可选的 previous:以前的 lesson:课程 directory:目录 identical:相同的 instruction:说明 development server:开发服务器 client-side:客户…...
ok113i平台——qt+tslib支持usb触摸屏热插拔功能实现
问题:重新插拔设备,需要软件重启才能接收到触摸事件 愿因:是因为qt程序的tslib库的操作逻辑是在构造函数里面连接一次usb触摸设备,具体看如下文件内容: /home/forlinx/OK113i-linux-sdk/buildroot/buildroot-201902/dl…...
游戏引擎学习第112天
黑板:优化 今天的内容是关于优化的,主要讨论了如何在开发中提高代码的效率,尤其是当游戏的帧率出现问题时。优化并不总是要将代码做到最快,而是要确保代码足够高效,以避免性能问题。优化的过程是一个反复迭代的过程&a…...
深度学习笔记——LSTM
大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的LSTM知识点。 文章目录 LSTM(Long Short-Term Memory)LSTM 的核心部件LSTM 的公式和工作原理(1) 遗忘门&a…...
基于SpringBoot的“食物营养分析与推荐网站”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“食物营养分析与推荐网站”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统首页界面 系统注册…...
23种设计模式 - 工厂方法模式
模式定义 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,定义用于创建对象的接口,让子类决定实例化哪个类,从而将对象创建过程延迟到子类。其核心目的是解耦对象的创建与使用,增强系统的扩展…...
【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析①】
ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase01 作者:车端域控测试工程师 更新日期:2025年02月16日 关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 TC11-001测试用例 用例ID测试场景验证要点参考条款预期结果TC…...
Discuz! X3.5 根目录权限设置
在 Discuz! X3.5 中,根目录的权限设置是确保网站安全性和功能正常运行的关键。如果权限设置不当,可能会导致文件无法访问、安全问题(如文件被篡改)或功能异常。以下是关于 Discuz! X3.5 根目录权限设置的详细说明和建议: 1. 根目录位置 Discuz! X3.5 的根目录通常是网站的…...
建筑兔零基础自学python记录22|实战人脸识别项目——视频人脸识别(下)11
这次我们继续解读代码,我们主要来看下面两个部分; 至于人脸识别成功的要点我们在最后总结~ 具体代码学习: #定义人脸名称 def name():#预学习照片存放位置path M:/python/workspace/PythonProject/face/imagePaths[os.path.join(path,f) f…...
React之旅-02 创建项目
创建React项目,常用的方式有两种: 官方提供的脚手架,官网:https://create-react-app.dev/。如需创建名为 my-app 的项目,请运行如下命令: npx create-react-app my-app 使用Vite包,官网&…...
uniapp 滚动尺
scale组件代码(部分class样式使用到了uview1.0的样式) <template><view><view class"scale"><view class"pointer u-flex-col u-col-center"><u-icon name"arrow-down-fill" size"26&qu…...
Redux中间件redux-thunk和redux-saga的具体区别是什么?
Redux 中间件是增强 Redux 功能的重要工具,redux-thunk 和 redux-saga 是两个常用的中间件,它们在处理异步操作和副作用时提供了不同的方式和理念。以下是两者的具体区别: 1. 概念与设计理念 redux-thunk 简洁:redux-thunk 是一…...
Windows 启动 SSH 服务
Windows 启动 SSH 服务 一、OpenSSH Server 安装 以 Win10 系统为例 打开设置 -> 系统 -> 可选功能 在 添加的功能 查看是否安装了 OpenSSH 服务 或者 OpenSSH Server 如果没有安装,找到 系统->添加可选功能 -> 查看功能->搜索 OpenSSH 服务 ->…...
rust笔记1-学习资料推荐
学习Rust的Trait、生命周期和模式确实需要一些时间,尤其是当这些概念在其他语言中不常见时。以下是一些学习资料和建议,帮助你更好地理解这些概念: 1. 官方文档与书籍 《The Rust Programming Language》(俗称“The Book”&…...
MySQL 的存储引擎有哪些?它们之间有什么区别? MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么区别? MySQL 的索引类型有哪些?
MySQL 的存储引擎有哪些?它们之间有什么区别? 先来回顾以下我们业务场景下一般的数据库访问的过程应用——>server层 ——>存储引擎层——>磁盘 官网描述: InnoDB: MySQL 8.4 中的默认存储引擎。 InnoDB 是事务安全(符…...
【Linux探索学习】第二十六弹——进程通信:深入理解Linux中的进程通信
Linux探索学习: https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言: 在Linux操作系统中,进程通信(IPC)是操作系统的一项核心功能,用于在不同进程之间交换数据或…...
netcore https配置
一、生成证书 1. 安装 OpenSSL 如果尚未安装 OpenSSL,可以通过以下命令安装:Ubuntu/Debian:sudo apt update sudo apt install openssl CentOS/RHEL:sudo yum install openssl 2. 生成私钥 使用以下命令生成私钥文件(private.key)…...
遥感影像目标检测:从CNN(Faster-RCNN)到Transformer(DETR)
我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…...
rtcwake - Linux下定时唤醒计算机
rtcwake 是一个用于通过实时时钟(RTC)唤醒计算机的工具。它常用于在 Linux 系统中设置计算机在指定时间自动唤醒或关闭。以下是对命令 rtcwake -m off -s ${sleep_time} 的详细解析: 命令解析 bash复制 rtcwake -m off -s ${sleep_time} 1…...
使用vscode调试transformers源码
简要介绍如何使用vscode调试transformers源码 以源码的方式安装transformers(官方手册为Editable install) 优先参考官方手册 git clone https://github.com/huggingface/transformers.git cd transformers pip install -e .以下展示transformers/exa…...
LeetCode39
LeetCode39 目录 题目描述示例思路分析代码段代码逐行讲解复杂度分析总结的知识点整合总结 题目描述 给定一个无重复元素的整数数组 candidates 和一个目标整数 target,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复选…...
sql not in 优化
sql优化 1、not in 的优化 not in和not exists不会命中索引,可以优化为通过left join实现; 例如要查询存在于a表但不存在与b表的数据,比较容易理解的sql写法: SELECT * FROM table_a WHERE id NOT IN (SELECT aid FROM table_b)…...
同花顺C++面试题及参考答案
对 C 和 C++ 哪个更熟悉? 在编程语言的学习与实践中,我对 C++ 更为熟悉。C 语言作为一门经典的编程语言,以其高效、灵活和接近硬件的特性,在系统编程、嵌入式开发等领域占据着重要地位。它提供了丰富的底层操作能力,如指针操作、内存管理等,为开发者直接控制计算机资源提…...
PostgreSQL 添加索引导致崩溃,参数调整需谨慎--文档未必完全覆盖场景
开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共2720人左右 1 …...
【Linux Redis】关于用docker拉取Redis后,让虚拟机运行起来redis,并使得其可以连接到虚拟机外的navicat。
步骤一:拉取Redis镜像 docker pull redis 这个命令会下载最新版本的Redis镜像到你的本地Docker仓库中。你也可以指定一个具体的版本号,例如docker pull redis:6.2.6,来拉取特定版本的Redis镜像。 如果拉取遇到问题请参考【Linux AnolisOS】关…...
