1. 程式人生 > 程式設計 >Vue向後臺傳陣列資料,springboot接收vue傳的陣列資料例項

Vue向後臺傳陣列資料,springboot接收vue傳的陣列資料例項

用axios前臺程式碼:

 let menus_id = this.$refs.tree.getCheckedKeys(); //選單id [1,2,3]陣列
    this.$axios.get("/api/epidemic/roleMenus/addBath1",{params:{roleid:this.roleid,menusid:menus_id}}).then((result)=>{
      console.log(result)
    })

後臺程式碼:

@RequestMapping("/addBath1")
 public ResponseObj addBath1(Integer roleid,@RequestParam(value="menusid",required=false) Integer[] menusid) {
 //處理程式碼。。。。。。。
 return responseObj;
 }

前臺報錯:

xhr.js?ec6c:178 GET http://localhost:8080/api/epidemic/roleMenus/addBath1?roleid=2&menusid[]=1&menusid[]=101&menusid[]=102&menusid[]=103&menusid[]=104&menusid[]=2&menusid[]=201&menusid[]=202&menusid[]=203&menusid[]=3&menusid[]=301&menusid[]=302&menusid[]=303&menusid[]=304&menusid[]=4&menusid[]=401&menusid[]=402&menusid[]=403&menusid[]=404 400 (Bad Request)

dispatchXhrRequest @ xhr.js?ec6c:178
xhrAdapter @ xhr.js?ec6c:12
dispatchRequest @ dispatchRequest.js?c4bb:52
Promise.then (async)
request @ Axios.js?5e65:61
Axios.<computed> @ Axios.js?5e65:76
wrap @ bind.js?24ff:9
updRoleMenus @ AuthList.vue?e7ca:131
invokeWithErrorHandling @ vue.esm.js?efeb:1863
invoker @ vue.esm.js?efeb:2188
invokeWithErrorHandling @ vue.esm.js?efeb:1863
Vue.$emit @ vue.esm.js?efeb:3897
handleClick @ element-ui.common.js?ccbf:9417
invokeWithErrorHandling @ vue.esm.js?efeb:1863
invoker @ vue.esm.js?efeb:2188
original._wrapper @ vue.esm.js?efeb:7565
createError.js?16d0:16 Uncaught (in promise) Error: Request failed with status code 400
at createError (createError.js?16d0:16)
at settle (settle.js?db52:17)
at XMLHttpRequest.handleLoad (xhr.js?ec6c:61)

Vue向後臺傳陣列資料,springboot接收vue傳的陣列資料例項

百度到後臺改為:

@RequestMapping("/addBath1")
 public ResponseObj addBath1(Integer roleid,@RequestParam(value="menusid[]",required=false) Integer[] menusid) {
 //、、、、、、、、
 return responseObj;
 }

請求前臺依然報錯,這次後臺也報錯:

java.lang.IllegalArgumentException: Invalid character found in the request target [/epidemic/roleMenus/addBath1?roleid=2&menusid[]=1&menusid[]=101&menusid[]=102&menusid[]=103&menusid[]=104&menusid[]=2&menusid[]=201&menusid[]=202&menusid[]=203&menusid[]=3&menusid[]=301&menusid[]=302&menusid[]=303&menusid[]=304&menusid[]=4&menusid[]=401&menusid[]=402&menusid[]=403&menusid[]=404]. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:491) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.36.jar:9.0.36]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.36.jar:9.0.36]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]

Vue向後臺傳陣列資料,springboot接收vue傳的陣列資料例項

後來試了百度的一堆操作,依然沒解決,貌似tocmat版本太高?不清楚

最後百般嘗試,前臺用路徑傳參:

解決辦法:

前臺vue傳參程式碼:

 let menus_id = this.$refs.tree.getCheckedKeys(); //選單id [1,3]陣列

 this.$axios.get("/api/epidemic/roleMenus/addBath1?roleid="+this.roleid+"&menusid="+menus_id).then((result)=>{
   console.log(result)
   }).catch((err)=>{
    console.log("---出錯---!"+err.message)
   })
  },

後臺接收:

@RequestMapping("/addBath1")
 public ResponseObj addBath1(Integer roleid,required=false) Integer[] menusid) {
 //處理程式碼。。。。。。。
 return responseObj;
 }

通過這樣路徑傳參結果解決問題。。。。

補充知識:vue+springboot專案,前端傳送的物件中含有陣列、物件等屬性,傳到後端變為String,出現數據型別轉換問題:String不能轉換為陣列或物件

問題背景:

一個專案中包含員工、部門兩個表,員工和部門是多對一的關係。

員工表對應的bean是EmpBean,部門表對應的bean是DepBean。

EmpBean的屬性包含員工表的所有欄位(基本資料型別),還包含一個depBean(對應其所在部門的資訊,資料型別為DepBean)。

從資料庫查員工時,將員工資訊封裝在empBean(資料型別為EmpBean)中,也會通過表連線,將其所在的部門的資訊查出來封裝在depBean中。

前端有一個自定義的物件:emp(只包含員工表中欄位),更新員工資訊,先將後端傳過來的empBean複製給前端的bean,然後通過資料繫結,將使用者更改的資訊繫結到前端emp相應的屬性中,此時前端emp中也有depBean了。

前端使用者提交更新,會將前端emp傳給後端,此時,前端emp中depBean就是字串而不是物件,後端如果用empBean接收資料,就會出現資料型別轉換問題。

問題分析:

資料流如下:

表->後端bean->前端object1->前端object2->後端bean->表

前端接收資料之後,呈現在前端的頁面表格中。每一行資料對應著後端的一個empBean。

前端編輯emp資訊後,傳到後端,更新資料庫。

通過問題背景中的描述也可以知道,兩個方向的資料流動並不是平衡的,後端無論傳什麼,前端都能接收,但是前端只能傳字串,且後端只有在型別相容時才能接收資料。

複雜的資料型別(物件、陣列)可以順利地從後端傳到前端,但是再從前端傳回來時都變成了字串,後端不能接收了。

而且,上述問題中的depBean即使被成功傳到後端也沒什麼用。如果有用,也可以單獨作為一個物件,而不是前端emp的屬性傳到後端。

解決方案:

前端呈現員工資訊時,需要部門資訊。

前端更新員工資訊後,只需把更新的員工資訊傳回到後端即可。

1.empBean中包含depBean中所含有的全部欄位,但是不包含depBean物件。

可行,但是不規範,EmpBean中有大量的DepBean就很奇怪了。

2.後端單獨單獨查所有部門資訊,並把所有部門資訊封裝,傳遞到前端,然後前端呈現員工資訊時,根據關聯欄位取出需要的部門資訊。

可行,但是需要兩次查詢資料庫,且如果部門特別多呢?前端呈現員工資訊可以分頁,需要的資料是很少的。如果部門特別多,又需要單獨傳遞所有的部門資訊,資料量可能會很大。

3.根據分頁獲取的員工資訊,獲取相應的部門,並單獨封裝傳遞給前端。

可行,但是也是需要兩次查詢,而且後端處理資料的邏輯會變得比較複雜。

4.刪除object2中物件屬性(資料型別為物件等非基礎型別的屬性)

不可行。兩種刪除方法:

(1)、delete刪除的結果是undefined,但是還是存在這個屬性的。

(2)、屬性=undefined,也沒能刪除掉屬性,屬性為object object

(為什麼不刪除object1中屬性?object1用來接收後端資料並作為呈現資料的資料來源,所以不適合刪除。object2用來接收object的資料作為初始資料,並用來接收使用者輸入資料,然後傳回給後端,所以可以刪除其中無用的屬性)

5.在前端object1->前端object2這個過程中,使用可以排除物件中非基礎資料型別屬性的複製方法。

可行,object1接收後端資料,並根據需要呈現資料,且在編輯時複製給object2,作為初始資料。object2接收使用者通過瀏覽器(頁面)輸入或更新的資料,然後傳回給後端。資料從後端->前端,和從前端->後端需求是不一樣的,轉換就可以在前端object1->前端object2這個過程中進行。

6.在後端新增中間層dto,接收前端傳過來的物件empDto,再進行相應的處理,直接用來進行資料庫操作。或根據實際情況按需傳給empBean後,再進行資料庫操作。

可行,但是增加了一層,系統結構變了,而且除非建立封裝資料型別轉化的類或方法,不然將empDto資料傳遞給empBean的過程還是比較麻煩的(將empDto中對應員工資訊的屬性(基礎型別屬性)複製給empBean,將empBean中的depBean設定為null就好,因為不需要)。

而且前端傳過來的depBean,就是原來的depBean(更新員工資訊時),即使接收了,也沒什麼用。

總結:

我最終採取的是解決方案5。

方案4、5、6都嘗試過,1、2、3沒有嘗試過。

以上這篇Vue向後臺傳陣列資料,springboot接收vue傳的陣列資料例項就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。