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

原文地址:https://www.cnblogs.com/pejsidney/p/9634935.html

时间: 2024-10-06 14:58:52

springmvc接收前台(如ajax)传来的数组list,set等图文详解的相关文章

django 接受 ajax 传来的数组对象

django 接受 ajax 传来的数组对象 发送:ajax 通过 POST 方式传来一个数组 接收:django 接受方式 array = request.POST.getlist('key[]') 其中,key为包含该数组的键值对的键. 尤其要注意"[]",少了它将不能接受成功 为什么要加"[]"? 分析前台发送数据,我们会发现:ajax自动给数组中的数据的键名后添加了"[]"

数组,异质结构以及指针的详解

数组,异质结构以及指针的详解 前言 昨天看了一部韩国电影,老千2,看到凌晨5点,不过发现韩国的棒子们确实养眼,女的贼拉漂亮,还有大尺度哦~ 咱们上一次分析了过程(方法)的实现,其中精妙的栈帧占据了首要的地位,不知道各位还能否记忆起来.今天咱们一起来看看数组的相关内容,相比之下,数组和流程控制与过程的实现难度差不多,尤其是动态数组可能还要稍微难一些,因为大家做好心理准备,不过呢,相信你每克服一个困难都是一种快乐,就像你看见一张好图,废了九牛二虎之力找到了种子那种感觉. 正文 数组简介 如果大家是一

C++中二维数组传参的方法详解

C++中二维数组传参的方法详解 首先需要明确,C++中其实没有多维数组,所谓的多维数组,其实就是数组的数组: 另外,数组中元素的个数也是数组类型的一部分. 当一个数组的元素仍然是数组时,通常使用2个维度来定义它,一个数组表示数组本身的大小,另一个维度表示其元素大小(它的元素也是数组): int ia[3][4]; //大小为3的数组,每个元素是含有4个整数的数组 int (*p)[4] = ia;//p指向含有4个整数的数组(指向第一个内层数组) 1 将给定第二维长度的二维数组作为形参传递 #i

jQuery实现ajax提交form表单(可以是提交json),用springmvc接收。图文详解

第一种方法(简单易用,防蚊虫): 1.1 从form表单到congtroller接收.1 是form表单,2 是ajax提交 3 springmvc接收 1.2 debug 看后台数据,看到了吧,userEO接收到数据了 1.3 有人想看看seralize和seralizeArray数据不同 seralize:id=1&name=xiaohua&age=18&sex=man seralizeArray[ id 1],[ name xiaohua],[ age 18],[ sex m

一维 + 二维树状数组 + 单点更新 + 区间更新 详解

树状数组详解: 假设一维数组为A[i](i=1,2,...n),则与它对应的树状数组C[i](i=1,2,...n)是这样定义的: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 + A4 C5 = A5 C6 = A5 + A6 ................. C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 ................ 如图可知: 为奇数的时候他是代表他本身,而为偶数的时候则是代表着自

springMVC接收前台传的日期

当前台传数据给spring的control时,如果后台方法的参数或参数对象的对应属性是基本类型或者string类型时,前台值自动的注入到后台方法参数或对象属性中.如果方法参数或对象属性不是基本类型或string,比如是date类型,则不能直接赋值. 解决方法有一下三种: 一.使用注解 1.在springmvc配置文件中开启注解<mvc:annotation-driven /> 2.在参数或对象属性上添加注解 如:如果是date类型可以添加@DateTimeFormat(pattern = &q

flask接收前台的ajax的数据

html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/index.css"> <script src="/static/js/j

Java基础--关于分支、循环、数组的部分练习题及详解

**-----分支题-----** 1.定义一个int类型的变量为x并赋值为5,如果x<10,则让x实现自增,并输出x最后的值. package com.eduask;  //包名 public class Test {   //类 public static void main(String[] args) {  //主函数 int x=5; //声明一个int类型的变量并初始化值为5 if(x<10){  //if分支,如果x的值小于10,x=5,符合题意,进入分支 x++;   //x实

数组几个常用方法的详解

join() 方法用于把数组中的所有元素放入一个字符串.元素是通过指定的分隔符进行分隔的. arrayObject.join(separator)separator 可选.指定要使用的分隔符.如果省略该参数,则使用逗号作为分隔符.返回一个字符串.该字符串是通过把 arrayObject 的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入 separator 字符串而生成的. concat() 方法用于连接两个或多个数组. arrayObject.concat(arrayX,ar