axios利用params/data發(fā)送參數(shù)給springboot?controlle的正確獲取方式
引言
今天有人遇到接口調(diào)用不通的情況,粗略看了一下是axios跨域請(qǐng)求引起了。找到問(wèn)題,處理就簡(jiǎn)單多了。
但是我看其代碼,發(fā)現(xiàn)比較有意思
export function agentlist(query) { return request({ url: /agent/list', method: 'get', params: query }) } export function editagent(data) { return request({ url: '/agent/editagent', method: 'post', data:data }) } export function deleteagent(id) { return request({ url: '/agent/delete', method: 'post', params:{id} }) }
上面的代碼中的request是axios實(shí)例,同是post卻出現(xiàn)了data或params做數(shù)載體的情況。憑直覺(jué)該代碼會(huì)在后續(xù)請(qǐng)求中出現(xiàn)問(wèn)題,果不其然后續(xù)出現(xiàn)各種問(wèn)題。
出現(xiàn)的問(wèn)題主要是:前端傳遞參數(shù)給了springboot程序,但是程序中卻接收不到數(shù)據(jù)或只接收到部分?jǐn)?shù)據(jù)。出現(xiàn)問(wèn)題前后端代碼如下:
前端:
export function login(account, password, orgType) { return request({ url: '/webapi/login', method: 'post', data: {"loginId":account,"password":password,"orgType":orgType} )}
后端:
@PostMapping(value = "/login") public Result login(String loginId, String password, int orgType, HttpServletResponse response){ }
程序運(yùn)行異常:
java.lang.IllegalStateException: Optional int parameter 'orgType' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
問(wèn)題分析:
出現(xiàn)異常的原因看似orgType無(wú)法轉(zhuǎn)換為對(duì)象類型引發(fā)的,真實(shí)情況并非如此。真正的原因是Java中的代碼根本就無(wú)法獲取到3個(gè)參數(shù),前兩個(gè)是String類型在無(wú)法獲取參數(shù)的情況下會(huì)被賦值為null,第三個(gè)參數(shù)因是 int 類型,因無(wú)法賦值為null,故引發(fā)該異常。出現(xiàn)異常并非Java代碼寫(xiě)得不好,而是前后臺(tái)傳參銜接出了問(wèn)題。
前端數(shù)據(jù)發(fā)送網(wǎng)絡(luò)請(qǐng)求,注意下面的數(shù)據(jù)的格式:
前端數(shù)據(jù)確實(shí)發(fā)送了,但是數(shù)據(jù)的格式為json格式。
服務(wù)器端POST請(qǐng)求獲取參數(shù),要求的參數(shù)格式為:key=value&key2=value2&key.....,因此服務(wù)器端無(wú)法獲取數(shù)據(jù)也就好理解了。
解決上述解決方案:
前端解決方案1
export function login(account, password, orgType) {return request({ url: '/webapi/login', method: 'post', data: "loginId="+account+ "&password="+password+"&orgType="+orgType }) }
手動(dòng)構(gòu)造服務(wù)器端需要的數(shù)據(jù)格式,此時(shí)再次執(zhí)行客戶端程序,并跟蹤網(wǎng)絡(luò)請(qǐng)求如下圖,springboot程序正常獲取到數(shù)據(jù)。
上面這種方案雖能解決問(wèn)題,但太機(jī)械,用來(lái)分析問(wèn)題可以,生產(chǎn)中就行不通了。
前端方案2
export function login(account, password, orgType) { return request({ url: '/webapi/login', method: 'post', params: {"loginId":account, "password":password,"orgType":orgType} }) }
將 axios 中的參數(shù)載體由 data 改為 params,此時(shí)再次執(zhí)行客戶端程序,并跟蹤網(wǎng)絡(luò)請(qǐng)求如下圖,springboot程序正常獲取到數(shù)據(jù)。
上面這種解決方案,將要發(fā)送的數(shù)據(jù)對(duì)象以params做載體發(fā)送時(shí),axios會(huì)把數(shù)據(jù)對(duì)象的屬性與值拼成 k=v&k=v 格式,但這些數(shù)據(jù)是作為 Query String(放在url中的參數(shù)) 傳遞給后臺(tái)程序的,因此并非真正意義上post傳參(實(shí)際是post方式向增加了參數(shù)url地址,提交空數(shù)據(jù)??)。
總結(jié):通過(guò)上面的兩個(gè)前端解決方案,現(xiàn)在就很容易搞清楚 axios 中的 params與data 傳參的區(qū)別了。
params 傳參,參數(shù)以 k=v&k=v 格式放置在 url 中傳遞。
data傳參,參數(shù)會(huì)收到Request Header中的 Content-Type 類型的影響,但它們肯定不會(huì)出現(xiàn)在url中,我們就暫且任務(wù) data 的參數(shù)會(huì)在 form表單中吧。
前端解決方案3
使用 qs 來(lái)實(shí)現(xiàn) json 對(duì)象的 k=v 格式化
import qs form 'qs' export function login(account, password, orgType) { return request({ url: '/webapi/login', method: 'post', data: qs.stringify({"loginId":account, "password":password,"orgType":orgType}) }) }
如此一來(lái),就非常方便的將json對(duì)象序列化為url格式,json對(duì)象屬性再多也不再是負(fù)擔(dān)。
現(xiàn)在 json 當(dāng)紅,js模塊化.....超速發(fā)展,我們的項(xiàng)目中再傳一個(gè)兩個(gè)的參數(shù)太low,現(xiàn)在流行傳對(duì)象。要前端傳遞對(duì)象到后端 springboot web 程序,現(xiàn)在這都是事兒。
前端傳遞json對(duì)象到springboot web 程序
1、在前端使用 data 作為載體傳遞 json 對(duì)象
var jsonObject = {"loginId":account, "password":password,"orgType":orgType}; export function login(obj) { return request({ url: '/webapi/login', method: 'post', data: obj }) } login(jsonObject);
2、Springboot后端
class LoginModel{ String loginId,passowrd; public String getLoginId() { return loginId; } public void setLoginId(String loginId) { this.loginId = loginId; } public String getPassowrd() { return passowrd; } public void setPassowrd(String passowrd) { this.passowrd = passowrd; } public Integer getOrgType() { return orgType; } public void setOrgType(Integer orgType) { this.orgType = orgType; } Integer orgType; } @PostMapping(value = "/login") public Result login(@RequestBody LoginModel model, HttpServletResponse response){}
springboot web端,通過(guò)@RequestBody注解將自動(dòng)收集請(qǐng)求的 payload 中的數(shù)據(jù),并將數(shù)據(jù)反序列化為 LoginModel對(duì)象。
簡(jiǎn)單總結(jié)一下 springboot中關(guān)于 @RequsetParam、@RequestBody與不加注解獲取參數(shù)的區(qū)別
1、@RequsetParam 獲取 k=v 格式的參數(shù),get/post都可以
2、@RequestBody 獲取payload中的數(shù)據(jù),對(duì)于前端傳遞的 json 對(duì)象在 springboot web中反序列化尤為方便,同時(shí)它還支持獲取二進(jìn)制字節(jié)數(shù)據(jù)等。
3、在不適用注解獲取參數(shù)時(shí),默認(rèn)@RequsetParam機(jī)制,并且要求前端傳遞的參數(shù)名稱與springboot web 在的參數(shù)名稱一致,否則無(wú)法獲取到數(shù)據(jù)。
最后在說(shuō)明一點(diǎn),用于反序列化的 Java 類,最好不要使用 java基本數(shù)據(jù)類型,盡量使用 基本類型的包裝類型,如上面LoginModel中的 Integer,這樣就可以在前端不傳對(duì)應(yīng)參數(shù)時(shí)保持為null??
總結(jié)
到此這篇關(guān)于axios利用params/data發(fā)送參數(shù)給springboot controlle的正確獲取方式的文章就介紹到這了,更多相關(guān)axios用params/data發(fā)送參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)百度地圖鼠標(biāo)滑動(dòng)事件顯示、隱藏
這篇文章主要介紹了javascript實(shí)現(xiàn)百度地圖鼠標(biāo)滑動(dòng)事件顯示、隱藏的思路和方法,十分的實(shí)用,這里推薦給小伙伴們,有需要的朋友可以參考下。2015-04-04使用JS在瀏覽器中判斷當(dāng)前網(wǎng)絡(luò)連接狀態(tài)的幾種方法
本篇文章主要介紹了使用JS在瀏覽器中判斷當(dāng)前網(wǎng)絡(luò)狀態(tài)的幾種方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05layer.prompt使文本框?yàn)榭盏那闆r下也能點(diǎn)擊確定的方法
今天小編就為大家分享一篇layer.prompt使文本框?yàn)榭盏那闆r下也能點(diǎn)擊確定的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JS實(shí)現(xiàn)簡(jiǎn)單九宮格抽獎(jiǎng)
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)單九宮格抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06JavaScript數(shù)據(jù)可視化:ECharts制作地圖
這篇文章主要介紹了Echarts實(shí)現(xiàn)可視化地圖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08javascript tips提示框組件實(shí)現(xiàn)代碼
一個(gè)簡(jiǎn)單的類似title的提示效果,但現(xiàn)實(shí)內(nèi)容可以很豐富,以上js另存為tip.js,下面是使用的demo。2010-11-11