springmvc接收前台(可以是ajax)传来的数组list,map,set等集合,复杂对象集合等图文详解

简介:

springmvc接收前台(可以是ajax)传来的数组list,map,set等集合,复杂对象集合等图文详解http://www.bieryun.com/1205.html

常见的解决方案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

[html] view plain copy

  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页面

[html] view plain copy

  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>

 

[html] view plain copy

  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:

[html] view plain copy

  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.         })

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,是否可以用其他的我没有测试。

[html] view plain copy

  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 支持:

[html] view plain copy

  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接收就可以了。

亲测可行。

相关文章
|
6月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
402 1
|
9月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
630 1
|
6月前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。
|
10月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
690 156
|
10月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
575 0
|
10月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
149 0
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
1910 1
|
运维 关系型数据库 Java
PolarDB产品使用问题之使用List或Range分区表时,Java代码是否需要进行改动
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
Java API Apache
怎么在在 Java 中对List进行分区
本文介绍了如何将列表拆分为给定大小的子列表。尽管标准Java集合API未直接支持此功能,但Guava和Apache Commons Collections提供了相关API。
552 1
下一篇
开通oss服务