axios 用 params/data 發送參數給 springboot controller,如何才能正確獲取

今天有人遇到接口調用不通的狀況,粗略看了一下是axios跨域請求引發了。找到問題,處理就簡單多了。前端

可是我看其代碼,發現比較有意思java

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實例,同是post卻出現了data或params作數載體的狀況。憑直覺該代碼會在後續請求中出現問題,果不其而後續出現各類問題。ios

出現的問題主要是:前端傳遞參數給了springboot程序,可是程序中卻接收不到數據或只接收到部分數據。出現問題先後端代碼以下:web

 前端:spring

export function login(account, password, orgType) { return request({ url: '/webapi/login', method: 'post', data: {"loginId":account,"password":password,"orgType":orgType} )}

後端:json

@PostMapping(value = "/login") public Result login(String loginId, String password, int orgType, HttpServletResponse response){ }

程序運行異常:axios

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.後端

問題分析:api

出現異常的緣由看似orgType沒法轉換爲對象類型引起的,真實狀況並不是如此。真正的緣由是Java中的代碼根本就沒法獲取到3個參數,前兩個是String類型在沒法獲取參數的狀況下會被賦值爲null,第三個參數因是 int 類型,因沒法賦值爲null,故引起該異常。出現異常並不是Java代碼寫得很差,而是先後臺傳參銜接出了問題。跨域

前端數據發送網絡請求,注意下面的數據的格式:

前端數據確實發送了,可是數據的格式爲json格式。

服務器端POST請求獲取參數,要求的參數格式爲:key=value&key2=value2&key.....,所以服務器端沒法獲取數據也就好理解了。

解決上述解決方案:

前端解決方案1

export function login(account, password, orgType) {return request({ url: '/webapi/login', method: 'post', data: "loginId="+account+ "&password="+password+"&orgType="+orgType }) }

手動構造服務器端須要的數據格式,此時再次執行客戶端程序,並跟蹤網絡請求以下圖,springboot程序正常獲取到數據。

上面這種方案雖能解決問題,但太機械,用來分析問題能夠,生產中就行不通了。

前端方案2

export function login(account, password, orgType) { return request({ url: '/webapi/login', method: 'post', params: {"loginId":account, "password":password,"orgType":orgType} }) }

將 axios 中的參數載體由 data 改成 params,此時再次執行客戶端程序,並跟蹤網絡請求以下圖,springboot程序正常獲取到數據。 

上面這種解決方案,將要發送的數據對象以params作載體發送時,axios會把數據對象的屬性與值拼成 k=v&k=v 格式,但這些數據是做爲 Query String(放在url中的參數) 傳遞給後臺程序的,所以並不是真正意義上post傳參(實際是post方式向增長了參數url地址,提交空數據😀)。

總結:經過上面的兩個前端解決方案,如今就很容易搞清楚 axios 中的 params與data 傳參的區別了。

params 傳參,參數以 k=v&k=v 格式放置在 url 中傳遞。

data傳參,參數會收到Request Header中的 Content-Type 類型的影響,但它們確定不會出如今url中,咱們就暫且任務 data 的參數會在 form表單中吧。

前端解決方案3

使用 qs 來實現 json 對象的 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}) }) }

如此一來,就很是方便的將json對象序列化爲url格式,json對象屬性再多也再也不是負擔。

如今 json 當紅,js模塊化.....超速發展,咱們的項目中再傳一個兩個的參數太low,如今流行傳對象。要前端傳遞對象到後端 springboot web 程序,如今這都是事兒。

前端傳遞json對象到springboot web 程序

一、在前端使用 data 做爲載體傳遞 json 對象

var jsonObject = {"loginId":account, "password":password,"orgType":orgType}; export function login(obj) { return request({ url: '/webapi/login', method: 'post', data: obj }) } login(jsonObject);

二、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端,經過@RequestBody註解將自動收集請求的 payload 中的數據,並將數據反序列化爲 LoginModel對象。

簡單總結一下 springboot中關於 @RequsetParam、@RequestBody與不加註解獲取參數的區別

一、@RequsetParam 獲取 k=v 格式的參數,get/post均可以

二、@RequestBody 獲取payload中的數據,對於前端傳遞的 json 對象在 springboot web中反序列化尤其方便,同時它還支持獲取二進制字節數據等。

三、在不適用註解獲取參數時,默認@RequsetParam機制,而且要求前端傳遞的參數名稱與 springboot web 在的參數名稱一致,不然沒法獲取到數據。

最後在說明一點,用於反序列化的 Java 類,最好不要使用 java基本數據類型,儘可能使用 基本類型的包裝類型,如上面LoginModel中的 Integer,這樣就能夠在前端不傳對應參數時保持爲null👌

相關文章
相關標籤/搜索