SpringBoot中@RequestBody的偽表單提交場景
@RequestBody是什么?
@RequestBody是 Spring MVC/Spring Boot 中處理 HTTP 請求的核心注解,它的核心作用是:將 HTTP 請求體中的數(shù)據(jù)(通常是 JSON/XML 格式)自動解析并綁定到方法的參數(shù)對象上。
Spring MVC 框架默認參數(shù)解析行為:
在默認配置下,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ù)來源的默認規(guī)則,明確指定參數(shù)數(shù)據(jù)來源為 HTTP 請求體,并自動完成 JSON 到 Java 對象的轉(zhuǎn)換,把字段值一一賦值進去。
是否需要加@RequestBody
| 場景 | 是否需要加 @RequestBody | 備注 |
|---|---|---|
| POST/PUT 請求 | ? 必須加 | 參數(shù)是 JSON 格式(放在請求體) |
| GET 請求 | ? 不能加 | GET 請求沒有請求體,參數(shù)只能在 URL 中 |
| 表單提交 | ? 不加 | 用 @RequestParam 或直接綁定對象即可 |
| 參數(shù)是 XML 格式 | ? 必須加 | 解析請求體中的 XML 數(shù)據(jù) |
場景 1:傳統(tǒng)表單提交(最常見,無需加 @RequestBody)
這是原生 <form> 標簽或前端模擬的表單提交,特征是:
請求頭 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:偽表單提交(實際是 JSON,需要加 @RequestBody)
有些前端會用表單提交的寫法,但實際傳的是 JSON 數(shù)據(jù):
請求頭 Content-Type: application/json;
參數(shù)是 JSON 字符串(而非 key=value),放在請求體中。
這種場景本質(zhì)是JSON 請求體提交,只是前端寫法像表單,必須加 @RequestBody
偽表單提交舉例
前端用表單提交的寫法,但實際傳的是 JSON 數(shù)據(jù),偽表單提交舉例如下
表單提交的代碼:視覺和交互層面,用了 Element UI 的 <el-form> 組件,搭配 <el-form-item>、<el-input>、<el-radio-group> 等表單類組件,呈現(xiàn)出表單填寫的形態(tài),符合前端開發(fā)中表單寫法的認知。
<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="狀態(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 對象做雙向綁定,每個表單項都直接關(guān)聯(lián) dataForm 的子字段,里面包含了攝像頭的所有信息:
dataForm: {
cameraInfoId: '',
communityId: '',
cameraName: '',
macID: '',
direction: '1',
seq: '1',
state: 1,
remark: ''
}
這是多個字段組成的復(fù)雜數(shù)據(jù),不是單個的鍵值對,而是一個完整的對象
再看前端的數(shù)據(jù)提交時把完整對象傳給后端,點擊確定按鈕觸發(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
})
}
先校驗表單,通過后把 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 標準定義的媒體類型,專門表示請求體里的數(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ī)則處理請求體,當看到請求頭時 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 中,默認情況下參數(shù)綁定是從 URL 或表單(x-www-form-urlencoded)中解析,只有通過 @RequestBody 注解才能讓 Spring 主動解析請求體中的 JSON 字符串,并映射到入?yún)⒌?Java 實體類(若不使用該注解,Spring 無法自動完成這個綁定)。
到此這篇關(guān)于SpringBoot中@RequestBody的偽表單提交場景的文章就介紹到這了,更多相關(guān)SpringBoot @RequestBody表單提交內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 解讀@RequestBody的正確使用方法
- 快速解決SpringMVC @RequestBody 用map接收請求參數(shù)的問題
- 詳解SpringMVC @RequestBody接收Json對象字符串
- @ResponseBody 和 @RequestBody 注解的區(qū)別
- SpringMVC restful 注解之@RequestBody進行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 根據(jù)前端返回的字段名進行查詢數(shù)據(jù)
本文介紹了如何在Java中使用SpringDataJPA實現(xiàn)動態(tài)查詢功能,以便根據(jù)前端傳遞的字段名動態(tài)構(gòu)建查詢語句,通過創(chuàng)建實體類、Repository接口、構(gòu)建動態(tài)查詢、在Service層和Controller中使用動態(tài)查詢,實現(xiàn)了前后端分離架構(gòu)中的靈活查詢需求2024-11-11
SpringCloud中數(shù)據(jù)認證加密的方法總結(jié)
在當今分布式系統(tǒng)的日益復(fù)雜和信息傳遞的廣泛網(wǎng)絡(luò)化環(huán)境中,數(shù)據(jù)的加密和認證作為保障信息傳遞安全的關(guān)鍵手段,Spring?Cloud,作為一套構(gòu)建微服務(wù)架構(gòu)的強大框架,提供了多種靈活而強大的數(shù)據(jù)加密和認證方式,本文給大家總結(jié)了SpringCloud數(shù)據(jù)認證加密的方法2024-03-03
java循環(huán)刪除List元素報錯的原因分析與解決
大家在工作中應(yīng)該都會遇到從List集合中刪除某一個或多個元素的業(yè)務(wù)場景,相信大家都會避開在循環(huán)里面刪除元素,使用其他方式處理,這是為什么呢,下面小編就來和大家詳細聊聊2023-11-11
Spring Data JPA 簡單查詢--方法定義規(guī)則(詳解)
下面小編就為大家?guī)硪黄猄pring Data JPA 簡單查詢--方法定義規(guī)則(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04

