一、Postman介绍
Postman 的核心特征与用途:
- 是一款接口测试工具,支持 HTTP 等协议的接口请求发送、响应结果查看。
- 主要用于后端开发 / 测试人员独立验证接口功能,无需依赖前端代码。
- 常见功能包括接口用例管理、参数化测试、响应断言等,是开发流程中前后端分离协作的常用工具之一。
- 背景问题:测试后端方法时需编写前端代码,过程繁琐;互联网项目分工细化后,后端工程师无需掌握前端技能。
- 解决方案:后端工程师可通过专业接口测试工具测试程序,此处选用 Postman。
二、传参介绍
1.普通传参,也就是通过查询字符串来传参
- 原理 :通过 URL 的
查询字符串(?后的部分)传递参数,格式为key1=value1&key2=value2。
URL的格式如下:


- Postman 操作 :在
Params标签页填写KEY和VALUE,Postman 会自动拼接在 URL 后(如name=zhangsan&age=18)。 - 适用场景:GET 请求传参(也支持 POST,但更常用在 GET)、参数简单且无需加密的场景。
问题1:Postman 的 Params 栏到底在做什么?
你在 Params 栏填key=userName、value=张三,Postman 并没有 "单独发数据",而是帮你做了「手动拼接 URL」的偷懒操作:
- 你填完 Params 后,Postman 会自动把
userName=张三&passWord=123拼到 URL 的?后面; - 最终发送给后端的请求 URL 是:
http://你的域名/login?userName=张三&passWord=123; - 你可以直接看 Postman 的 URL 输入框 ------ 填完 Params 后,URL 会自动多出
?xxx=xxx的部分,这就是证据。
| 操作方式 | 最终发送的请求 URL | 后端是否能接收到值 | 本质 |
|---|---|---|---|
| Params 栏填 key/value | login?userName=张三&passWord=123 |
✅ 能接收到 | 自动拼接 URL 参数 |
| 手动在 URL 后加?key=value | login?userName=张三&passWord=123 |
✅ 能接收到 | 手动拼接 URL 参数 |
| 想在 Body 里传参(GET) | 无效(GET 无 Body) | ❌ 接收不到 | 违反 HTTP 协议 |
重点!!!:Params 不是 "先到地址再赋值",而是先拼接成完整 URL,再一次性发送请求到后端 ------ 后端拿到的是 "带参数的完整 URL",再从中解析参数。
问题2:GET 请求为啥能 "写操作"?
"GET 一般用来读取数据",这是HTTP 协议的 "规范建议",不是强制约束:
- 规范层面 :HTTP 协议给 GET/POST 定义了语义:
- GET:安全、幂等(多次请求结果一致),建议用于 "读取数据"(查列表、查详情);
- POST:非幂等,建议用于 "写数据"(新增、修改、删除)。
- 技术层面 :GET/POST 只是 HTTP 请求的 "方法标识",后端完全可以在 GET 接口里写业务逻辑(比如修改数据库、登录校验)------ 比如
login接口,本质是 "校验用户信息"(既不是纯读,也不是纯写),用 GET 也能跑通。 - 为什么不推荐 GET 做写操作?
- URL 长度有限(不同浏览器 / 服务器限制不同,一般几千字符),传参多了会截断;
- URL会被 浏览器 / 服务器记录(比如日志、历史记录),密码这类敏感数据用 GET 传会泄露(你这个例子里 passWord 放 URL 里就很危险);
- 不符合 RESTful 接口规范,团队协作时容易混乱。
简单说:GET 能做 "写操作" 是技术可行,但规范上不推荐。
问题3:"第一次写 URL 到后端,拼接后为啥还能进后端?"
用登录接口举例子,完整请求流程是这样的:
- 你在 Postman 填基础 URL:
http://localhost:8080/login; - 你在 Params 栏填
userName=test&passWord=123,Postman 自动拼接成完整 URL:http://localhost:8080/login?userName=test&passWord=123; - 你点击 "发送",Postman 基于这个完整 URL 发送 GET 请求(HTTP 协议把 URL、请求头、空 Body 打包);
- 后端服务器(比如 Tomcat)接收到这个请求,解析 URL:
- 先截取出
/login,匹配到你写的@RequestMapping("/login")的方法; - 再从 URL 的
?后面截取出userName=test&passWord=123,解析成键值对; - SpringMVC 把解析后的键值对,按名字赋值给方法的
userName和passWord参数;
- 先截取出
- 执行你的方法,打印参数,返回结果。
👉 总结:"基础 URL" 只是 "地址",拼接参数后的 "完整 URL" 才是 "带参数的地址"------ 后端只接收一次完整请求,先按地址找方法,再按参数名赋值,没有 "两次进入后端"。
| 操作项 | GET 版本(Params) | POST 版本(Body) |
|---|---|---|
| 请求方法 | GET | POST |
| URL | http://localhost:8080/login |
http://localhost:8080/login |
| 参数位置 | Params 栏填 key/value(拼 URL) | Body→x-www-form-urlencoded 填 key/value(放 Body) |
| 敏感数据安全性 | 差(URL 可见) | 好(Body 里,日志默认不记录) |
| 规范程度 | 不推荐(登录属于写操作) | 推荐(符合 HTTP 语义) |
2.form-data(完整表⽰为:multipart/form-data)
- 原理 :是 HTTP 表单提交的一种编码方式,通过
multipart格式分隔不同参数(支持文件 / 非文件参数)。 - 对应请求头 :
Content-Type: multipart/form-data。

- Postman 操作 :在
Body标签页选择form-data,填写KEY和VALUE(若传文件,可将VALUE类型切换为File)。 - 适用场景:需要上传文件(图片、文档等)的接口,或表单中同时包含普通字段与文件的场景。
3. x-www-form-urlencoded
- 原理 :是 HTTP 表单默认的编码方式,参数会被编码为
key1=value1&key2=value2格式(与查询字符串格式相同,但参数放在请求体中)。 - 对应请求头 :
Content-Type: application/x-www-form-urlencoded。

- Postman 操作 :在
Body标签页选择x-www-form-urlencoded,填写KEY和VALUE。 - 适用场景:普通表单提交(无文件)的 POST 请求,是接口传参的常用方式之一。
4. raw
- 原理:直接传递 "纯文本格式" 的内容,支持多种文本类型(需手动指定格式)。
- 支持格式 :Text、JSON、XML、HTML、JavaScript 等(在 Postman 的
raw下拉框选择)。

- Postman 操作 :在
Body标签页选择raw,选择对应格式后,在编辑框输入文本内容(如 JSON 格式的{"name":"zhangsan","age":18})。 - 适用场景:传递结构化数据(如 JSON、XML)的接口(目前后端接口最常用的传参方式之一)。
三、SpringMVC 接收参数时 "基础类型 vs 包装类型" 的注意事项
1.基础类型的 "非空限制"
Java 的基础类型(如int)不能为null ,而 SpringMVC 接收参数时,若参数没传,会默认赋值为null------ 这就会导致 "基础类型接收null" 的矛盾,从而触发错误。
2. 3 个场景的具体分析
1. 正常传参(正确情况)
- 请求 URL:
http://127.0.0.1:8080/param/m1/int?age=1 - 后端方法:
method1GetInt(int age) - 结果:后端成功解析
age=1(int类型匹配),返回 "接收到参数 age:1",HTTP 状态码 200(正常)。
2. 不传参数(触发 500 错误)
- 请求 URL:
http://127.0.0.1:8080/param/m1/int(无age参数) - 后端逻辑:SpringMVC 没拿到
age参数,尝试给int age赋值为null,但 **int是基础类型不能存null**,触发IllegalStateException异常。 - 结果:HTTP 状态码 500(服务器内部错误),日志提示 "
int参数不能转为 null,建议用包装类型"。
3. 传参类型不匹配(触发 400 错误)
- 请求 URL:
http://127.0.0.1:8080/param/m1/int?age=abc(age是字符串 "abc") - 后端逻辑:SpringMVC 尝试把 "abc" 转为
int类型,转换失败。 - 结果:HTTP 状态码 400(请求参数错误),因为 "参数类型不匹配"。
3.企业开发建议
对于可能为空的参数 ,优先用包装类型 (如Integer/Boolean)接收,避免因 "参数未传" 触发 500 错误;若参数是必填项,可结合@RequestParam(required = true)强制要求传参。
通用结论:
| 状态码 | 核心含义 | 通俗定位 | 典型原因 |
|---|---|---|---|
| 400 | Bad Request(请求错误) | 前端 / 客户端错 | 1. 参数类型不匹配(比如传 abc 给 int 参数);2. 参数格式错误(比如 JSON 缺引号);3. 必传参数没传(后端标了 required=true);4. 请求体格式非法(比如 XML 标签没闭合)。 |
| 500 | Internal Server Error | 后端 / 服务器错 | 1. 代码逻辑异常(比如空指针 NPE);2. 类型转换错误(比如 int 接 null);3. 数据库操作失败(比如连不上库);4. 第三方接口调用抛异常且未捕获。 |
简单记:
- 400:请求本身有问题(后端能接收到请求,但解析 / 校验通不过),前端传的参数 / 格式不符合后端要求;
- 500:后端处理请求时崩了(请求能正常到后端,但执行代码时抛了未处理的异常)。
1. 400 也可能是后端的 "锅"
比如后端定义了@RequestParam(required = true)要求传name参数,但文档没告诉前端,前端没传导致 400------ 本质是后端 "接口设计 / 文档没写清楚",而非前端编码错误。
2. 500 也可能是 "环境 / 依赖" 问题(非代码写错)
比如后端代码本身没问题,但服务器磁盘满了、数据库连接池耗尽、第三方接口挂了,导致后端执行时抛异常,返回 500------ 这是运维 / 环境问题,不是代码写错。
3. 特殊情况:后端 "主动返回 400/500"
规范的后端会主动返回 400 (比如参数校验失败时,用ResponseEntity.status(400).body("参数错误")),也会主动返回 500(比如系统内部错误时,统一封装异常返回)------ 这种情况是后端 "有意识的设计",而非 "写错了"。
三、实战定位小技巧(比单纯看状态码更准)
- 看 400:先查「前端传的参数是否符合后端接口文档」(类型、必传项、格式);
- 看 500:先查「后端日志」(找异常栈),看是代码逻辑(NPE / 类型转换)、环境(数据库 / 缓存)还是依赖问题;
- 若 400 但前端传参完全符合文档,大概率是后端校验逻辑写错了。
总结
日常沟通中说 "400 是前端错,500 是后端错" 完全没问题;但定位问题时,要结合「请求内容 + 后端日志」进一步确认,避免绝对化判断。