GET与POST请求详解:区别、POST请求体格式及Controller接收方案

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

一、GET请求与POST请求核心区别

GET和POST同属HTTP请求方法,本质差异源于HTTP协议设计语义数据传输机制,并非简单的“参数位置不同”。以下从核心维度做对比梳理:

设计语义

用于获取/查询服务器资源,无副作用(幂等)

用于提交/修改服务器资源,非幂等(多次请求可能产生不同结果)

数据传输位置

数据拼接在URL地址栏(Query参数),可见性高

数据存放在请求体(Request Body),URL无参数,隐蔽性更强

数据长度限制

受浏览器/服务器URL长度限制(通常2KB-8KB),不适合传大量数据

无显性长度限制,由服务器配置决定,支持大容量数据传输

安全性

参数明文暴露,易被抓包、篡改,绝对不能传敏感数据

参数在请求体,相对隐蔽;仍需HTTPS加密,适合传账号、密码等敏感信息

缓存机制

默认被浏览器、代理服务器缓存,可复用请求结果

默认不缓存,需手动配置缓存规则

历史记录/书签

可加入浏览器历史记录,支持生成书签

不会保留在历史记录,无法生成书签

编码类型

仅支持ASCII字符,非ASCII需手动转码

支持多种编码(表单、JSON、二进制、文件等),适配各类数据格式

误区纠正:GET和POST的安全性、长度限制并非协议强制规定,而是浏览器/服务器的实现限制;POST也并非绝对安全,仅解决了参数可见性问题。

二、POST请求体的4种主流格式(Content-Type)

POST请求通过Content-Type请求头标识请求体格式,日常开发中核心有4种,覆盖绝大多数业务场景:

1. application/x-www-form-urlencoded(默认表单格式)

浏览器原生表单默认格式,数据以键值对&拼接形式传输,类似GET的Query参数,仅存放于请求体。仅支持文本数据,不支持文件上传

示例:username=zhangsan&password=123456

2. multipart/form-data(多部分表单格式)

专门用于文件上传+文本参数混合传输,请求体被分割为多个独立部分,每部分携带独立请求头,支持二进制文件、文本参数同时提交。

3. application/json(JSON格式)

前后端分离主流格式,请求体为标准JSON字符串,支持复杂对象、数组、嵌套结构传输,可读性和扩展性极强,是接口开发首选。

示例:{"username":"zhangsan","age":20,"hobbies":["篮球","读书"]}

4. binary(二进制流格式,application/octet-stream)

纯二进制数据传输,无固定结构,通常用于传输单个文件、字节流,不支持键值对参数,多用于文件下载、大文件流式上传。

三、Spring Boot Controller对应接收方式

针对上述4种POST请求体格式,Spring Boot提供了专属注解和接收方式,以下为实操代码示例:

1. 接收 application/x-www-form-urlencoded 格式

使用@RequestParam注解接收单个键值对,或用实体类+省略注解自动映射(Spring会自动绑定表单参数到实体属性)。

@RestController
@RequestMapping("/post")
public class PostController {
    // 单个参数接收
    @PostMapping("/form1")
    public String form1(@RequestParam String username, @RequestParam String password) {
        return "接收表单参数:username=" + username + ", password=" + password;
    }

    // 实体类自动映射
    @PostMapping("/form2")
    public String form2(User user) {
        return "接收实体参数:" + user.toString();
    }
}
// 实体类
class User {
    private String username;
    private String password;
    // getter/setter/toString
}

2. 接收 multipart/form-data 格式(文件+参数)

文本参数用@RequestParam,文件用MultipartFile接收;多文件/混合场景可用@RequestPart注解。

@PostMapping("/upload")
public String upload(@RequestParam String remark, @RequestParam MultipartFile file) {
    // 获取文件名
    String fileName = file.getOriginalFilename();
    // 文件处理逻辑(存储、解析等)
    return "上传备注:" + remark + ",文件名:" + fileName;
}

// 多文件上传
@PostMapping("/uploadBatch")
public String uploadBatch(@RequestParam MultipartFile[] files) {
    return "批量上传文件数:" + files.length;
}

3. 接收 application/json 格式

必须使用@RequestBody注解,将JSON字符串自动反序列化为Java实体类/Map集合,仅支持POST/PUT等带请求体的请求

@PostMapping("/json")
public String json(@RequestBody User user) {
    return "接收JSON参数:" + user.toString();
}

// 接收Map类型(无需实体类)
@PostMapping("/jsonMap")
public String jsonMap(@RequestBody Map<String, Object> paramMap) {
    return "接收Map参数:" + paramMap.toString();
}

4. 接收 binary 二进制流格式

通过HttpServletRequest获取输入流,直接读取二进制数据,适用于纯文件流传输。

@PostMapping("/binary")
public String binary(HttpServletRequest request) throws IOException {
    // 获取输入流读取二进制数据
    InputStream inputStream = request.getInputStream();
    // 字节数组接收文件流
    byte[] bytes = inputStream.readAllBytes();
    return "接收二进制数据长度:" + bytes.length;
}

四、补充注意事项

  • @RequestBody 冲突问题:一个接口只能有一个@RequestBody注解,无法同时接收多个JSON对象;复杂场景可封装为嵌套实体类。
  • 文件上传限制:Spring Boot默认文件上传大小有限制,需在application.yml配置修改:spring.servlet.multipart.max-file-size=100MB。
  • 参数必填校验:可搭配@NotBlank、@NotNull等校验注解,实现参数合法性校验。
  • GET请求也可携带请求体,但不符合HTTP协议语义,绝大多数服务器不支持,严禁生产环境使用。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Spring 文章被收录于专栏

本专栏聚焦Spring全生态体系,从IoC/AOP核心原理入手,覆盖Spring Boot自动配置、事务管理、Web开发等实战内容。拆解循环依赖、动态代理等高频面试难点,助力开发者从入门到精通,打通单体到微服务的技术链路,解决企业级开发痛点,提升架构设计与问题排查能力,成为Java后端进阶的必备技术专栏。

全部评论

相关推荐

03-17 23:54
黑龙江大学 Java
来个白菜也好啊qaq:可以的,大厂有的缺打手
点赞 评论 收藏
分享
发一下问题给大家参考,攒攒人品!1.项目拷打2.实习拷打3.检索融合的具体流程是什么?召回后有没有做&nbsp;Rerank?4.Rerank&nbsp;后返回几个块(Chunk)?有没有针对这个返回数量做过验证?5.Rerank&nbsp;后的&nbsp;TopK&nbsp;截断是怎么做的?为什么是这个值?有没有其他截断方案?6.讲一下上下文工程(Context&nbsp;Engineering),Agent&nbsp;的记忆(Memory)是怎么做的?7.请详细讲解分布式令牌桶限流的实现。8.漏桶算法(Leaky&nbsp;Bucket)的原理讲一下。9。滑动窗口算法限流讲一下。如果用代码实现,滑动窗口的结构体会包含哪些字段?10.滑动窗口和令牌桶相比有什么缺点?11.在&nbsp;Redis&nbsp;中,你会用什么数据结构来实现滑动窗口限流?12.LRU&nbsp;缓存的实现原理讲一下。13.布隆过滤器(Bloom&nbsp;Filter)的底层原理和适用场景讲一下。14.MySQL&nbsp;索引会在哪些情况下失效?15.在使用&nbsp;LIKE&nbsp;进行模糊查询时,索引什么情况下会失效?16.MySQL&nbsp;的事务隔离级别有哪些?如何保证一致性?17.详细说说&nbsp;MVCC&nbsp;的实现,ReadView&nbsp;的生成时机是怎样的?18.在不同的隔离级别下,一个事务分别会创造几个&nbsp;ReadView?19.MySQL&nbsp;都有哪些锁?它们的作用分别是什么?20.为什么选择&nbsp;Python&nbsp;和&nbsp;Go&nbsp;作为技术栈?在处理并发时有什么区别?21.手撕代码:实现反转链表
查看21道真题和解析
点赞 评论 收藏
分享
现在前端的就业环境真的很...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务