1. 程式人生 > >springmvc接收前臺(如ajax)傳來的數組list,set等圖文詳解

springmvc接收前臺(如ajax)傳來的數組list,set等圖文詳解

報錯 ipp dem req snippet main src 關於 暫時

ref:https://blog.csdn.net/wabiaozia/article/details/50803581

前言:

相信很人都被springmvc接收數組問題折磨過,查過幾個解決方案,都不能很好的解決。那些方法一般存在一個問題:把接收到的數據結構轉換成你想要的結構時,不好處理。為什麽說不好處理下文有具體例子介紹(見1.2)。

1 本文springmvc版本為3.1 ,ecplise:月神(luna),tomcat:7.0,jdk:1.6,maven:3.0.

2 我博客所有文章目錄:http://blog.csdn.net/wabiaozia

3 註:百度鏈接頁面異常,點此鏈接恢復正常:點擊打開鏈接

常見的解決方案VS我要介紹的方案:

在springmvc接收數組對象List<user>時:

批量刪除比較簡單,用我的解決方案一的十分之一功力就可以解決,傳個id數組就行了,後臺根據id數組刪除就行了。麻煩的是對一 個對象的數組,進行批量新增修改,這時,如果可以把前臺傳來的數據,直接封裝到對象的數組(List<user>)中:即數據封裝到list的同時,也把name,pwd兩個屬性,封裝到user對象中,就會簡化後面對數據的處理。

一:常見的解決方案

1.1博客上看到的一些解決方案:

著重介紹下引入新的"參數解析器",使用“springmvc內置的支持”,這兩個方案,為什麽要著重介紹呢?因為我發現很多人都是從這裏拷貝的,但是沒有拷貝完整,所以導致有人在文章下面評論:樓主,你真的測試過這個方法嗎?你確定這個辦法可行? 我覺得引入新的“參數解析器是很好的辦法”,濤哥(京東)寫的"參數解析器"點我:我是外鏈,使用“springmvc內置的支持”點我:我是外鏈。而且開濤在這個專欄裏也寫了參數綁定裏的源碼,推薦可以去看看。但是項目組內是否允許你這樣使用,團隊的學習維護成本是個問題。

1.2還有一個作者寫的:

點我:我是外鏈這個我測試過,可行,但是不好處理接收的數據。為什麽這麽說呢:我想接受的數據是User對象的數組,但是接收的數據是:[{name=111, pwd=111},{name=222, pwd=222}],不能自動封裝到我的對象裏,沒有把name,pwd,封裝到User對象中。
下面是我的測試:

實體類MyDomain

  1. class MyDomain{
  2. private String name;
  3. private String pwd;
  4. ..........
  5. }

我想封裝到 List<MyDomain> 中,list裏是兩個MyDomain對象,封裝到 List的同時也把name和pwd兩個屬性也封裝到MyDomain對象中,見下圖中 上半部分圖。但是他的list裏是兩個LinkedHasnMap,name和pwd兩個屬性沒有封裝到MyDomain對象中,見圖下半部分1,不是我想要的list裏是兩個MyDomain對象。誰有好的辦法可以發給我。。。。。。。

debug跟一下:

技術分享圖片

二:我的方案解決方案-My solution

**轉載標明鏈接:http://blog.csdn.net/wabiaozia/article/details/50803581

2.1 方案一

我最常用的解決方案是RequestParam,直接提交表單

jsp頁面

  1. <form .....method="post"..............>
  2. 姓名1:<input type="text" name="id" value="">
  3. 年齡1:<input type="text" name="age" value="">
  4. 地址1:<input type="text" name="address" value="">
  5. 姓名2:<input type="text" name="id" value="">
  6. 年齡2:<input type="text" name="age" value="">
  7. 地址2:<input type="text" name="address" value=""><pre code_snippet_id="1597573" snippet_file_name="blog_20160304_1_2164278" name="code" class="html"></form>

  1. controller
  2. @RequestMapping("/...........")
  3. public String update(Export export, @RequestParam("id")String[] ids,
  4. @RequestParam("age")String[] ages,
  5. @RequestParam("address")String[] address,
  6. Model model){
  7. //ids,ages,addres接收進來的是什麽樣的數據呢?
  8. //接收的數據類型是ids[111,222,333],ages[222,333,444],address[sss,ddd,yyy]
  9. //拓展:若用@RequestParam("id")String ids接收,則傳進來的是一個個String字符串,用逗號分隔。例如ids:“abc,cde,def”
  10. //批量增加
  11. for(int i=0,len=ids.length;i<len;i++){
  12. User user=new User();
  13. user.setId(ids[i]);
  14. user.setAge(ages[i]);
  15. user.setAddress(address[i]);
  16. userDao.isnert(user);
  17. }
  18. }
  19. 這種方案適合特別修改刪除,而且相比用js拼接數據有個好處,不用在前端拼接參數。

2.2 方案二

由於後臺不能接收數組,所以要想辦法讓後臺接收數組,這樣就陷入了困境。這裏可以轉換下思路, 為什麽非要讓後臺接收數組呢?可以把數組序列化成Json字符串提交,後臺springmvc裏用@ RequestBody String 方式接收,然後把這個接收到的json串用json工具轉換為數組,這樣就解決了springmvc不能綁定對象數組的問題了。為什麽用和json相關的解決方案呢?現在json和java對象的轉換的工具特別多,也特別方便,而且網上有很多成熟的工具,jackson,Gson,fastjson.......等等,還有個重要的原因是,隨著前端框架的迅速發展,現在做項目都是前後端分離,前端傳的數據多是json,綜合以上最庸選擇使用和json相關的解決方案。

我這裏用了jackson處理。不會jackson的可以參考點我:我是外鏈和點我:我是外鏈。

JSON庫之性能比較:JSON.simple VS GSON VS Jackson VS JSONP:http://www.open-open.com/lib/view/open1434377191317.html

js:

  1. var users = JSON.stringify([
  2. {name: "wabiaozai1", pwd: "123"},
  3. {name: "wabiaozai2", pwd: "123"}
  4. ]);
  5. $.ajax({
  6. type: "post",
  7. url: "./wabiaozai",
  8. data:users ,
  9. contentType: "application/json; charset=utf-8",
  10. dataType: "json",
  11. success: function (response, ifo) {
  12. alert("success");
  13. }, error: function () {
  14. alert("error");
  15. }
  16. })

{2018/05/05 新增

這個url的路徑寫法也介紹下。雖然大家都會寫,但是小白讀者碰到url請求404問題後會手忙腳亂不知如何處理,所以我簡要介紹下吧,會的讀者直接跳過。1 如果是springboot,默認直接請求這個url "/wabiaozai"就行了,如果你的applicatoin.properties或applicatoin.yml中配置了上下問路徑如server.context-path=/spring-boot,則請求的url為"/spring-boot/wabiaozai " 2 如果直接用的springmvc,請求的url為 "/你的上下文路徑/wabiaozai"或者"./wabiaozai"。若你手動設置tomcat裏的path為空,直接請求url "/wabiaozai" }

js中註意兩個細節:

dataType:‘json‘,//預期的服務器響應的數據類型。

contentType: "application/json; charset=utf-8",//發送數據到服務器時所使用的內容類型。默認是:"application/x-www-form-urlencoded"。
關於ajax分享兩篇文章:jquery_ajax: 點我:我是外鏈 ajax: 點擊打開鏈接 如果不加contentType,myDomain接收的數據為類似%7B%22id%22%3A243%2C%name%22%3A4%2C%22age%22%3A1048%2C%22格式,json轉換會報錯,

controller層

我這裏用的@requestBody,是否可以用其他的我沒有測試。
  1. @RequestMapping(value = "/wabiaozai", method = RequestMethod.POST)
  2. public void myDomain(HttpServletRequest request, @RequestBody String myDomain) throws Exception{
  3. ObjectMapper objectMapper = new ObjectMapper();
  4. JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, MyDomain.class);
  5. List<MyDomain> list = objectMapper.readValue(myDomain, javaType);
  6. System.out.println("");
  7. }
這裏提一點@RequestBody的相關知識 1 該註解用來處理Content-Type編碼方式: 一般不是適用於application/x-www-form-urlencoded編碼的內容,而是適用於application/json, application/xml等;它是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body,然後綁定到相應的bean上的。因為配置有FormHttpMessageConverter,所以也可以用來處理 application/x-www-form-urlencoded的內容,處理完的結果放在一個MultiValueMap<String, String>裏,這種情況在某些特殊需求下使用,詳情查看FormHttpMessageConverter api;更多介紹見:點擊打開鏈接 2 官方文檔是這樣描述的(spring3.2.18裏關於註解@RequestBody的描述): 使用@RequestBody 註解映射請求體時:方法參數中的@RequestBody 註解表示方法參數應該被綁定了 HTTP請求體的值。請求體到方法參數的轉換是由 HttpMessageConverter 完成的。HttpMessageConverter 負責將 HTTP 請求信息轉換成對象,以及將對
象轉換回一個 HTTP 響應體。對於@RequestBody 註解,RequestMappingHandlerAdapter 提供了以下幾種默認的HttpMessageConverter 支持:
  1. ? ByteArrayHttpMessageConverter 用以轉換字節數組
  2. ? StringHttpMessageConverter 用以轉換字符串
  3. ? FormHttpMessageConverter 用以將表格數據轉換成MultiValueMap<String, String>或從 MultiValueMap<String,String>中轉換出表格數據
  4. ? SourceHttpMessageConverter 用於javax.xml.transform.Source 類的互相轉換....
更多請參照官方文檔。。。。 三:debug看結果 ok,代碼寫完了,我們debug一下看結果: 技術分享圖片 用json轉換:不會jackson的可以參考http://www.blogjava.net/bolo/archive/2014/04/16/412533.html 技術分享圖片 ..............................................................................................呵呵,成功..............................................................................................

四:思考

這個是在前端拼接組合的users,

var users = JSON.stringify([
{name: "wabiaozai1", pwd: "123"},
{name: "wabiaozai2", pwd: "123"}
]);

有沒有辦法不要拼?我要告訴你

http://blog.csdn.net/lutinghuan/article/details/46820023 裏面的第4種方法:將表單對象序列化成Json字符串提交,以List接收 ,把對象轉換成json數組,我已經測試過,也成功轉換,但究竟有bug嗎暫時未知。

五:spring3.2 直接支持泛型集合

##註:spring 3.2 直接支持泛型集合,如List<Sample> Map<String, Sample>等集合泛型

具體步驟

1 要配置驅動註解<mvc:annotation-driven/> ,裏面註冊了會把json綁定到list的"Bean實例"(註冊的實例會因為spring版本的不同而不同,具體註冊裏哪些實例詳見官網)

2 前臺傳json數組,後臺直接@RequestBody List<Color> list接收就可以了。

親測可行。

也可以參見:http://jinnianshilongnian.iteye.com/blog/1835431 評論裏demo

六:寫在最後

20160427重新排版.

20160428重新配圖.

有真的不要組合對象傳遞參數的嗎?

欲知後事如何請聽下回分解。。。。。。。。。。。

博客所有文章目錄:http://blog.csdn.net/wabiaozia

轉載標明鏈接:http://blog.csdn.net/wabiaozia/article/details/50803581

springmvc接收前臺(如ajax)傳來的數組list,set等圖文詳解