SpringBoot請求參數(shù)還可以這樣玩?很少有人知道?
環(huán)境:Spring2.7.18
1. 簡介
在Web開發(fā)中,請求參數(shù)處理是核心功能之一。SpringBoot提供了靈活且強大的參數(shù)綁定機制,能夠自動將HTTP請求中的參數(shù)(如查詢參數(shù)、路徑變量、表單數(shù)據(jù)、JSON等)映射到控制器方法的參數(shù)上。無論是簡單類型、復(fù)雜對象還是集合類型,SpringBoot都能通過注解(如@RequestParam、@PathVariable、@RequestBody等)實現(xiàn)無縫對接,極大地提升了開發(fā)效率與應(yīng)用的健壯性。此外,它還支持?jǐn)?shù)據(jù)校驗、自定義參數(shù)解析器等高級特性,滿足各種復(fù)雜的業(yè)務(wù)需求。對于表單數(shù)據(jù),當(dāng)設(shè)置Content-Type為multipart/form-data時,我們確實可以方便地實現(xiàn)文件的上傳以及普通文本字段的提交。然而,在某些復(fù)雜場景中,我們可能希望除了上傳文件外,還能將其他字段以非普通文本類型(如application/json、application/xml等)提交,這種場景又該如何實現(xiàn)呢?
對于application/json類型的數(shù)據(jù),客戶端通常會將請求的內(nèi)容以JSON格式添加到HTTP請求的body中,并設(shè)置請求的Content-Type為application/json。在SpringBoot后端,當(dāng)處理這種類型的數(shù)據(jù)時,我們只需在控制器方法的相應(yīng)參數(shù)上使用@RequestBody注解,SpringBoot便會自動將請求體中的JSON數(shù)據(jù)轉(zhuǎn)換成Java對象(如DTO、VO等)。
接下來我詳細(xì)的介紹對于這種復(fù)雜的應(yīng)用場景在SpringBoot中是如何進行處理的,這需要前后端配合。
2. 實戰(zhàn)案例
既然要包含json對象,又要包含附近,所以這里我們需要結(jié)合@RequestPart注解,用該注解分別來指定要獲取請求中哪部分內(nèi)容,而Spring MVC底層會更加你的類型進行自動的轉(zhuǎn)換。
2.1 基本操作
接口定義
@PostMapping("/requestpart")
public Object requestpart(
@RequestPart("user") User user,
@RequestPart("file") MultipartFile file
) throws Exception {
// TODO
file.transferTo(new File("f://m.png")) ;
return user ;
}
這里每個參數(shù)都通過@RequestPart來指定分別獲取請求中的哪部分內(nèi)容。接口定義完后,接下來看前端要如何處理
前端請求處理
前端我們需要借助FormData來添加每一項表單數(shù)據(jù),同時還需要為每一項指明你的數(shù)據(jù)類型,如下示例:
let form = new FormData()
// 文件附件
form.append('file', document.querySelector('#file').files[0])
let data = {age: 5000, name: '中國????'}
// 通過Blob來構(gòu)建一個不可變、原始數(shù)據(jù)的類文件對象,同時指明你數(shù)據(jù)類型
let user = new Blob([JSON.stringify(data)], { type: 'application/json' })
form.append('user', user)
axios({
method: 'post',
url: 'http://localhost:8080/api/request/requestpart',
// 設(shè)置請求header,這里設(shè)置multipart/mixed也可以
headers: {
'Content-Type': 'multipart/form-data'
},
data: form
})
粗糙的前端頁面
圖片
后端接口成功的接收了json數(shù)據(jù),再看看請求長什么樣。
圖片
通過請求Payload知道,每個請求部分都有自己的Content-Type。在后端接口會根據(jù)每個Content-Type進行數(shù)據(jù)類型的轉(zhuǎn)換。
2.2 更多請求類型
你還可以指定更多的類型。
public Object requestpart(
@RequestPart("user") User user,
@RequestPart("xml") String xml,
@RequestPart("file") MultipartFile file)
前端通過通過Blob對象來指定數(shù)據(jù)類型。
let form = new FormData()
// other
// 制定類型為xml
let xml = new Blob(['<message><title>@RequestPart請求參數(shù)處理</title></message>'], {type: 'application/xml'})
form.append('xml', xml)
請求情況。
圖片
如果你還有其它類型,可以任意的指定,只要后端有對應(yīng)的參數(shù)解析器即可(后端如何轉(zhuǎn)換類型會根據(jù)你請求的情況比如:根據(jù)Content-Type)。
2.3 參數(shù)校驗
與@RequestBody請求參數(shù)一樣,這里的@RequestPart也可以使用基于注解的方式進行參數(shù)的校驗,如下示例:
@PostMapping("/requestpart")
public Object requestpart(
@Validated @RequestPart("user") User user,
BindingResult result,
@RequestPart(name = "xml", required = false) String xml,
@RequestPart("file") MultipartFile file
) throws Exception {
// TODO
if (result.hasErrors()) {
return result.toString() ;
}
return user ;
}
// User實體對象
public static class User {
private Integer age ;
@NotEmpty
private String name ;
// Getters, Setters
}
前端輸出結(jié)果;
圖片
注意:請求錯誤對象的位置,否則將在后端控制臺拋出異常,當(dāng)然如果你有全局異常處理也就無所謂了。