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

 

  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.  
     
  6.  
    姓名2: <input type="text" name="id" value="">
  7.  
    年齡2: <input type="text" name="age" value="">
  8.  
    地址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.  
    //批量增加
  12.  
    for(int i=0,len=ids.length;i <len;i++){
  13.  
     
  14.  
    User user=new User();
  15.  
    user.setId(ids[i]);
  16.  
    user.setAge(ages[i]);
  17.  
    user.setAddress(address[i]);
  18.  
     
  19.  
    userDao.isnert(user);
  20.  
    }
  21.  
    }
  22.  
    這種方案適合特別修改刪除,而且相比用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.  
     
  6.  
    $.ajax({
  7.  
    type: "post",
  8.  
    url: "./wabiaozai",
  9.  
    data:users ,
  10.  
    contentType: "application/json; charset=utf-8",
  11.  
    dataType: "json",
  12.  
    success: function (response, ifo) {
  13.  
    alert("success");
  14.  
    }, error: function () {
  15.  
    alert("error");
  16.  
    }
  17.  
    })

 

{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.  
     
  4.  
    ObjectMapper objectMapper = new ObjectMapper();
  5.  
    JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, MyDomain.class);
  6.  
    List <MyDomain> list = objectMapper.readValue(myDomain, javaType);
  7.  
     
  8.  
    System.out.println("");
  9.  
    }
 
 這里提一點@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 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM