SpringBoot中@RequestBody的伪表单提交场景

 更新时间:2025年12月29日 10:40:57   作者:期待のcode  
@RequestBody是Spring MVC/Spring Boot中用于处理HTTP请求体数据的核心注解,主要用于将JSON/XML格式的请求体数据自动绑定到方法参数对象上, 下面就来介绍一下如何使用

@RequestBody是什么?

@RequestBody是 Spring MVC/Spring Boot 中处理 HTTP 请求的核心注解,它的核心作用是:将 HTTP 请求体中的数据(通常是 JSON/XML 格式)自动解析并绑定到方法的参数对象上。

Spring MVC 框架默认参数解析行为:
在默认配置下,Spring MVC 的请求参数解析器(HandlerMethodArgumentResolver)仅会解析符合 application/x-www-form-urlencoded 媒体类型的请求参数(如 URL 路径参数、查询字符串参数、表单提交的键值对参数),不会主动读取 HTTP 请求体的 JSON 数据,也不支持将请求体中的 JSON 格式数据自动绑定到控制器方法的参数对象上。

@RequestBody 注解用于声明控制器方法的参数需从 HTTP 请求体中获取数据,并触发 Spring MVC 的消息转换器(HttpMessageConverter)完成以下核心操作:
读取请求体中的原始字符数据(通常为 JSON 格式);
根据参数声明的 Java 类型,将 JSON 数据反序列化为对应的 Java 对象;
将反序列化后的 Java 对象注入到控制器方法的参数中,完成参数绑定。

简言之,该注解覆盖了 Spring MVC 对参数来源的默认规则,明确指定参数数据来源为 HTTP 请求体,并自动完成 JSON 到 Java 对象的转换,把字段值一一赋值进去。

是否需要加@RequestBody

场景是否需要加 @RequestBody备注
POST/PUT 请求✅ 必须加参数是 JSON 格式(放在请求体)
GET 请求❌ 不能加GET 请求没有请求体,参数只能在 URL 中
表单提交❌ 不加用 @RequestParam 或直接绑定对象即可
参数是 XML 格式✅ 必须加解析请求体中的 XML 数据

场景 1:传统表单提交(最常见,无需加 @RequestBody)
这是原生 <form> 标签或前端模拟的表单提交,特征是:
请求头 Content-Type: application/x-www-form-urlencoded;
参数以 key1=value1&key2=value2 的形式放在请求体。

场景 2:带文件的表单提交(multipart/form-data,无需加 @RequestBody)
如果表单包含文件上传,请求头是 Content-Type: multipart/form-data,同样不需要加 @RequestBody,需用 @RequestParam/@RequestPart 接收

场景 3:伪表单提交(实际是 JSON,需要加 @RequestBody)
有些前端会用表单提交的写法,但实际传的是 JSON 数据:
请求头 Content-Type: application/json;
参数是 JSON 字符串(而非 key=value),放在请求体中。
这种场景本质是JSON 请求体提交,只是前端写法像表单,必须加 @RequestBody

伪表单提交举例

前端用表单提交的写法,但实际传的是 JSON 数据,伪表单提交举例如下

表单提交的代码:视觉和交互层面,用了 Element UI 的 <el-form> 组件,搭配 <el-form-item><el-input><el-radio-group> 等表单类组件,呈现出表单填写的形态,符合前端开发中表单写法的认知。

    <el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="100px" style="width:95%;" @keyup.enter.native="dataFormSubmit()">
      <el-row>
        <el-col :span="24">
          <el-form-item label="摄像头名称" prop="cameraName">
            <el-input v-model="dataForm.cameraName" placeholder="请输入摄像头名称" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="IP地址" prop="macID">
            <el-input v-model="dataForm.macID" placeholder="请输入IP地址(必须唯一)" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="方向" prop="direction">
            <el-radio-group v-model="dataForm.direction">
              <el-radio :label="1">进场</el-radio>
              <el-radio :label="2">出场</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="状态" prop="state">
            <el-radio-group v-model="dataForm.state">
              <el-radio :label="1">启用</el-radio>
              <el-radio :label="2">禁用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="排序" prop="seq">
            <el-input v-model="dataForm.seq" placeholder="请输入排序号" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="dataForm.remark" placeholder="请输入备注" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button type="danger" @click="visible=false">取 消</el-button>
      <el-button type="primary" @click="dataFormSubmit()">确 定</el-button>
    </span>

表单与 dataForm 对象做双向绑定,每个表单项都直接关联 dataForm 的子字段,里面包含了摄像头的所有信息:

dataForm: {
  cameraInfoId: '',
  communityId: '',
  cameraName: '',
  macID: '',
  direction: '1',
  seq: '1',
  state: 1,
  remark: ''
}

这是多个字段组成的复杂数据,不是单个的键值对,而是一个完整的对象

再看前端的数据提交时把完整对象传给后端,点击确定按钮触发的自定义的 dataFormSubmit() 方法,触发异步请求:

dataFormSubmit() {
  this.$refs['dataForm'].validate((valid) => {
    if (valid) {
      const param = {
        'cameraInfoId': this.dataForm.cameraInfoId,
        'communityId': this.dataForm.communityId,
        'cameraName': this.dataForm.cameraName,
        'macID': this.dataForm.macID,
        'direction': this.dataForm.direction,
        'seq': this.dataForm.seq,
        'state': this.dataForm.state,
        'remark': this.dataForm.remark
      }
      if (!this.dataForm.cameraInfoId) {
        add(param).then(res => {
          if (res.code === 200) {
            this.visible = false
            this.$emit('refreshDataList')
            this.$message.success(res.msg)
          } else {
            this.$message.error(res.msg)
          }
        })
      } else {
        edit(param).then(res => {
          if (res.code === 200) {
            this.visible = false
            this.$emit('refreshDataList')
            this.$message.success(res.msg)
          } else {
            this.$message.error(res.msg)
          }
        })
      }
    }
  })
export function add(data) {
  return request({
    url: '/sys/camera/add',
    method: 'post',
    data
  })
}

export function edit(data) {
  return request({
    url: '/sys/camera/edit',
    method: 'put',
    data
  })
}

先校验表单,通过后把 dataForm 的所有字段组装成param对象(和dataForm内容一致);
判断是新增 / 编辑:
新增:调用add(param),对应 POST 请求,把param作为data传给后端;
编辑:调用edit(param),对应 PUT 请求,同样把param作为data传给后端

前端向后端发新增的 HTTP 请求的过程
请求 URL为:/sys/camera/add
Request Body 请求体为:传输的是 JSON 数据

{
    "cameraInfoId": 0,
    "communityId": "19",
    "cameraName": "1号摄像头",
    "macID": "127.0.0.1",
    "direction": 2,
    "seq": "2",
    "state": 1,
    "remark": "高清摄像头"
}

Content-Type 请求头:Content-Type: application/json
其中 application/json 是 HTTP 标准定义的媒体类型,专门表示请求体里的数据是 JSON 格式的字符串

前端的 request 库(本质是 axios)会把 data 参数(也就是param对象)这个 JavaScript 对象转换成 JSON 字符串,再把这个 JSON 字符串放在 HTTP 请求的请求体(Request Body)里(而不是 URL 里),且自动添加 Content-Type: application/json 请求头。
后端接收到请求后,先读取 Content-Type 再决定用哪种解析规则处理请求体,当看到请求头时 Content-Type: application/json,Spring 会用JSON 解析器把请求体的 JSON 字符串解析成 Java 对象。

不管是新增(POST)还是编辑(PUT)都要传递多个字段的完整摄像头对象,这些数据量大且结构复杂,不可能拼在 URL 里(URL 长度有限、不安全、格式不支持),前端把完整对象通过data参数放在请求体里传输,后端读取请求体里的 JSON,因此必须加@RequestBody。

总结:Spring MVC 中,默认情况下参数绑定是从 URL 或表单(x-www-form-urlencoded)中解析,只有通过 @RequestBody 注解才能让 Spring 主动解析请求体中的 JSON 字符串,并映射到入参的 Java 实体类(若不使用该注解,Spring 无法自动完成这个绑定)。

到此这篇关于SpringBoot中@RequestBody的伪表单提交场景的文章就介绍到这了,更多相关SpringBoot @RequestBody表单提交内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java 根据前端返回的字段名进行查询数据

    java 根据前端返回的字段名进行查询数据

    本文介绍了如何在Java中使用SpringDataJPA实现动态查询功能,以便根据前端传递的字段名动态构建查询语句,通过创建实体类、Repository接口、构建动态查询、在Service层和Controller中使用动态查询,实现了前后端分离架构中的灵活查询需求
    2024-11-11
  • SpringCloud中数据认证加密的方法总结

    SpringCloud中数据认证加密的方法总结

    在当今分布式系统的日益复杂和信息传递的广泛网络化环境中,数据的加密和认证作为保障信息传递安全的关键手段,Spring Cloud,作为一套构建微服务架构的强大框架,提供了多种灵活而强大的数据加密和认证方式,本文给大家总结了SpringCloud数据认证加密的方法
    2024-03-03
  • MapReduce中ArrayWritable 使用指南

    MapReduce中ArrayWritable 使用指南

    MapReduce是一种编程模型,用于大规模数据集的并行运算。概念"Map(映射)"和"Reduce(归约)"和他们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。他极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。
    2014-08-08
  • Java的Spring框架的三种连接池的基本用法示例

    Java的Spring框架的三种连接池的基本用法示例

    这篇文章主要介绍了Java的Spring框架的三种连接池的基本用法示例,Spring框架是Java下注明的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-11-11
  • Java集合框架之Collection接口详解

    Java集合框架之Collection接口详解

    这篇文章主要为大家详细介绍了Java集合框架之Collection接口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 详解mybatis generator代码生成器的使用

    详解mybatis generator代码生成器的使用

    MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器。这篇文章主要介绍了mybatis generator代码生成器的使用,需要的朋友可以参考下
    2021-09-09
  • Spring Security的过滤器链机制

    Spring Security的过滤器链机制

    过滤器作为 ​Spring Security​ 的重中之重,我们需要了解其中的机制,这样我们才能根据业务需求的变化进行定制,今天来探讨一下 ​Spring Security​ 中的过滤器链机制
    2022-08-08
  • java循环删除List元素报错的原因分析与解决

    java循环删除List元素报错的原因分析与解决

    大家在工作中应该都会遇到从List集合中删除某一个或多个元素的业务场景,相信大家都会避开在循环里面删除元素,使用其他方式处理,这是为什么呢,下面小编就来和大家详细聊聊
    2023-11-11
  • Spring Data JPA 简单查询--方法定义规则(详解)

    Spring Data JPA 简单查询--方法定义规则(详解)

    下面小编就为大家带来一篇Spring Data JPA 简单查询--方法定义规则(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • java 使用线程做的一个简单的ATM存取款实例代码

    java 使用线程做的一个简单的ATM存取款实例代码

    线程 Thread 类,和 Runable 接口 比较两者的特点和应用领域.可以,直接继承线程Thread类。该方法编写简单,可以直接操作线程,适用于单重继承情况,因而不能在继承其他类,下面我们来看一个实例
    2013-08-08

最新评论