SpringBoot中@RequestBody的偽表單提交場景
@RequestBody是什么?
@RequestBody是 Spring MVC/Spring Boot 中處理 HTTP 請求的核心注解,它的核心作用是:將 HTTP 請求體中的數(shù)據(jù)(通常是 JSON/XML 格式)自動解析并綁定到方法的參數(shù)對象上。
Spring MVC 框架默認(rèn)參數(shù)解析行為:
在默認(rèn)配置下,Spring MVC 的請求參數(shù)解析器(HandlerMethodArgumentResolver)僅會解析符合 application/x-www-form-urlencoded 媒體類型的請求參數(shù)(如 URL 路徑參數(shù)、查詢字符串參數(shù)、表單提交的鍵值對參數(shù)),不會主動讀取 HTTP 請求體的 JSON 數(shù)據(jù),也不支持將請求體中的 JSON 格式數(shù)據(jù)自動綁定到控制器方法的參數(shù)對象上。
@RequestBody 注解用于聲明控制器方法的參數(shù)需從 HTTP 請求體中獲取數(shù)據(jù),并觸發(fā) Spring MVC 的消息轉(zhuǎn)換器(HttpMessageConverter)完成以下核心操作:
讀取請求體中的原始字符數(shù)據(jù)(通常為 JSON 格式);
根據(jù)參數(shù)聲明的 Java 類型,將 JSON 數(shù)據(jù)反序列化為對應(yīng)的 Java 對象;
將反序列化后的 Java 對象注入到控制器方法的參數(shù)中,完成參數(shù)綁定。
簡言之,該注解覆蓋了 Spring MVC 對參數(shù)來源的默認(rèn)規(guī)則,明確指定參數(shù)數(shù)據(jù)來源為 HTTP 請求體,并自動完成 JSON 到 Java 對象的轉(zhuǎn)換,把字段值一一賦值進(jìn)去。
是否需要加@RequestBody
| 場景 | 是否需要加 @RequestBody | 備注 |
|---|---|---|
| POST/PUT 請求 | ? 必須加 | 參數(shù)是 JSON 格式(放在請求體) |
| GET 請求 | ? 不能加 | GET 請求沒有請求體,參數(shù)只能在 URL 中 |
| 表單提交 | ? 不加 | 用 @RequestParam 或直接綁定對象即可 |
| 參數(shù)是 XML 格式 | ? 必須加 | 解析請求體中的 XML 數(shù)據(jù) |
場景 1:傳統(tǒng)表單提交(最常見,無需加 @RequestBody)
這是原生 <form> 標(biāo)簽或前端模擬的表單提交,特征是:
請求頭 Content-Type: application/x-www-form-urlencoded;
參數(shù)以 key1=value1&key2=value2 的形式放在請求體。
場景 2:帶文件的表單提交(multipart/form-data,無需加 @RequestBody)
如果表單包含文件上傳,請求頭是 Content-Type: multipart/form-data,同樣不需要加 @RequestBody,需用 @RequestParam/@RequestPart 接收
場景 3:偽表單提交(實(shí)際是 JSON,需要加 @RequestBody)
有些前端會用表單提交的寫法,但實(shí)際傳的是 JSON 數(shù)據(jù):
請求頭 Content-Type: application/json;
參數(shù)是 JSON 字符串(而非 key=value),放在請求體中。
這種場景本質(zhì)是JSON 請求體提交,只是前端寫法像表單,必須加 @RequestBody
偽表單提交舉例
前端用表單提交的寫法,但實(shí)際傳的是 JSON 數(shù)據(jù),偽表單提交舉例如下
表單提交的代碼:視覺和交互層面,用了 Element UI 的 <el-form> 組件,搭配 <el-form-item>、<el-input>、<el-radio-group> 等表單類組件,呈現(xiàn)出表單填寫的形態(tài),符合前端開發(fā)中表單寫法的認(rèn)知。
<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">進(jìn)場</el-radio>
<el-radio :label="2">出場</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="狀態(tài)" 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 對象做雙向綁定,每個表單項(xiàng)都直接關(guān)聯(lián) dataForm 的子字段,里面包含了攝像頭的所有信息:
dataForm: {
cameraInfoId: '',
communityId: '',
cameraName: '',
macID: '',
direction: '1',
seq: '1',
state: 1,
remark: ''
}
這是多個字段組成的復(fù)雜數(shù)據(jù),不是單個的鍵值對,而是一個完整的對象
再看前端的數(shù)據(jù)提交時把完整對象傳給后端,點(diǎn)擊確定按鈕觸發(fā)的自定義的 dataFormSubmit() 方法,觸發(fā)異步請求:
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
})
}
先校驗(yàn)表單,通過后把 dataForm 的所有字段組裝成param對象(和dataForm內(nèi)容一致);
判斷是新增 / 編輯:
新增:調(diào)用add(param),對應(yīng) POST 請求,把param作為data傳給后端;
編輯:調(diào)用edit(param),對應(yīng) PUT 請求,同樣把param作為data傳給后端
前端向后端發(fā)新增的 HTTP 請求的過程
請求 URL為:/sys/camera/add
Request Body 請求體為:傳輸?shù)氖?JSON 數(shù)據(jù)
{
"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 標(biāo)準(zhǔn)定義的媒體類型,專門表示請求體里的數(shù)據(jù)是 JSON 格式的字符串
前端的 request 庫(本質(zhì)是 axios)會把 data 參數(shù)(也就是param對象)這個 JavaScript 對象轉(zhuǎn)換成 JSON 字符串,再把這個 JSON 字符串放在 HTTP 請求的請求體(Request Body)里(而不是 URL 里),且自動添加 Content-Type: application/json 請求頭。
后端接收到請求后,先讀取 Content-Type 再決定用哪種解析規(guī)則處理請求體,當(dāng)看到請求頭時 Content-Type: application/json,Spring 會用JSON 解析器把請求體的 JSON 字符串解析成 Java 對象。
不管是新增(POST)還是編輯(PUT)都要傳遞多個字段的完整攝像頭對象,這些數(shù)據(jù)量大且結(jié)構(gòu)復(fù)雜,不可能拼在 URL 里(URL 長度有限、不安全、格式不支持),前端把完整對象通過data參數(shù)放在請求體里傳輸,后端讀取請求體里的 JSON,因此必須加@RequestBody。
總結(jié):Spring MVC 中,默認(rèn)情況下參數(shù)綁定是從 URL 或表單(x-www-form-urlencoded)中解析,只有通過 @RequestBody 注解才能讓 Spring 主動解析請求體中的 JSON 字符串,并映射到入?yún)⒌?Java 實(shí)體類(若不使用該注解,Spring 無法自動完成這個綁定)。
到此這篇關(guān)于SpringBoot中@RequestBody的偽表單提交場景的文章就介紹到這了,更多相關(guān)SpringBoot @RequestBody表單提交內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 解讀@RequestBody的正確使用方法
- 快速解決SpringMVC @RequestBody 用map接收請求參數(shù)的問題
- 詳解SpringMVC @RequestBody接收J(rèn)son對象字符串
- @ResponseBody 和 @RequestBody 注解的區(qū)別
- SpringMVC restful 注解之@RequestBody進(jìn)行json與object轉(zhuǎn)換
- springmvc @RequestBody String類型參數(shù)的使用
- 關(guān)于Springboot | @RequestBody 接收到的參數(shù)對象屬性為空的問題
- Springboot攔截器如何獲取@RequestBody參數(shù)
- 親測SpringBoot參數(shù)傳遞及@RequestBody注解---踩過的坑及解決
- springMvc注解之@ResponseBody和@RequestBody詳解
相關(guān)文章
java使用MulticastSocket實(shí)現(xiàn)基于廣播的多人聊天室
這篇文章主要為大家詳細(xì)介紹了java使用MulticastSocket實(shí)現(xiàn)基于廣播的多人聊天室,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01
SpringBoot使用Druid連接池進(jìn)行優(yōu)化完整指南
在 Spring Boot 中使用 Druid 連接池進(jìn)行極致優(yōu)化,需要從??核心參數(shù)調(diào)優(yōu)??,??監(jiān)控體系搭建,??安全增強(qiáng)??等多個維度綜合考慮,下面是詳細(xì)優(yōu)化策略,希望對大家有所幫助2025-07-07
springboot項(xiàng)目開啟https協(xié)議的項(xiàng)目實(shí)現(xiàn)
本文主要介紹了springboot項(xiàng)目開啟https協(xié)議的項(xiàng)目實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
IDEA2022搭建Spring?Cloud多模塊項(xiàng)目的詳細(xì)過程
這篇文章主要介紹了IDEA2022搭建Spring?Cloud多模塊項(xiàng)目,網(wǎng)上有很多教程父模塊都是通過maven的方式創(chuàng)建的,然后子模塊是通過Spring?Initalizr方式創(chuàng)建,這種方式父模塊無法管理子模塊的依賴仲裁,需要每個子模塊自行管理,就失去了父模塊的用處了2022-10-10
Java實(shí)現(xiàn)刪除文件中的指定內(nèi)容
在日常開發(fā)中,經(jīng)常需要對文本文件進(jìn)行批量處理,其中,刪除文件中指定內(nèi)容是最常見的需求之一,下面我們就來看看如何使用java實(shí)現(xiàn)刪除文件中的指定內(nèi)容吧2025-06-06

