springmvc接收前臺(如ajax)傳來的數組list,set等圖文詳解
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
- class MyDomain{
- private String name;
- private String pwd;
- ..........
- }
我想封裝到 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頁面
- <form .....method="post"..............>
- 姓名1:<input type="text" name="id" value="">
- 年齡1:<input type="text" name="age" value="">
- 地址1:<input type="text" name="address" value="">
- 姓名2:<input type="text" name="id" value="">
- 年齡2:<input type="text" name="age" value="">
- 地址2:<input type="text" name="address" value=""><pre code_snippet_id="1597573" snippet_file_name="blog_20160304_1_2164278" name="code" class="html"></form>
- controller
- @RequestMapping("/...........")
- public String update(Export export, @RequestParam("id")String[] ids,
- @RequestParam("age")String[] ages,
- @RequestParam("address")String[] address,
- Model model){
- //ids,ages,addres接收進來的是什麽樣的數據呢?
- //接收的數據類型是ids[111,222,333],ages[222,333,444],address[sss,ddd,yyy]
- //拓展:若用@RequestParam("id")String ids接收,則傳進來的是一個個String字符串,用逗號分隔。例如ids:“abc,cde,def”
- //批量增加
- for(int i=0,len=ids.length;i<len;i++){
- User user=new User();
- user.setId(ids[i]);
- user.setAge(ages[i]);
- user.setAddress(address[i]);
- userDao.isnert(user);
- }
- }
- 這種方案適合特別修改刪除,而且相比用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:
- var users = JSON.stringify([
- {name: "wabiaozai1", pwd: "123"},
- {name: "wabiaozai2", pwd: "123"}
- ]);
- $.ajax({
- type: "post",
- url: "./wabiaozai",
- data:users ,
- contentType: "application/json; charset=utf-8",
- dataType: "json",
- success: function (response, ifo) {
- alert("success");
- }, error: function () {
- alert("error");
- }
- })
{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,是否可以用其他的我沒有測試。- @RequestMapping(value = "/wabiaozai", method = RequestMethod.POST)
- public void myDomain(HttpServletRequest request, @RequestBody String myDomain) throws Exception{
- ObjectMapper objectMapper = new ObjectMapper();
- JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, MyDomain.class);
- List<MyDomain> list = objectMapper.readValue(myDomain, javaType);
- System.out.println("");
- }
象轉換回一個 HTTP 響應體。對於@RequestBody 註解,RequestMappingHandlerAdapter 提供了以下幾種默認的HttpMessageConverter 支持:
- ? ByteArrayHttpMessageConverter 用以轉換字節數組
- ? StringHttpMessageConverter 用以轉換字符串
- ? FormHttpMessageConverter 用以將表格數據轉換成MultiValueMap<String, String>或從 MultiValueMap<String,String>中轉換出表格數據
- ? SourceHttpMessageConverter 用於javax.xml.transform.Source 類的互相轉換....
四:思考
這個是在前端拼接組合的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等圖文詳解