(一)框架环境
前端:html , js, jquery
后端:SpringBoot,Spring,SpringMVC,Mybatis
项目DEMO:https://gitee.com/enbledeajous/AjaxTPDemo
总结:List和Map都能传,注意一些细节即可
(二)ajax传List
关键:ajax声明traditional:true。
在jquery早期,traditional属性默认为false,但如果是新版本的jquery,默认属性是ture,所以可能有 移植代码后不能跑的情况(jquery版本变更)
- 前端传参必须加traditional
- 默认的话,traditional为false时会进行深度序列化,servlet无法识别
- 我们可以通过设置traditional 为true阻止深度序列化。
- eg:
- --------------traditional:false的情况-------------------------------
- list=[1,2,3,4,5,6]
- 前端传过来是:list%5B%5D=1&list%5B%5D=2&list%5B%5D=3&list%5B%5D=4&list%5B%5D=5&list%5B%5D=6
- %5B%5D是[]的转义,这时候后台mvc解码错误,导致报错(不管List<>是什么,String/Integer等都一视同仁)
- --------------traditional:true的情况-------------------------------
- list=[1,2,3,4,5,6]
- 前端传过来是:list=1&list=2&list=3&list=4&list=5&list=6
- 这时候前端传参正常,但如果直接在Controller用List接收,报错java.lang.NoSuchMethodException: java.util.List.()
- (有兴趣可以了解下MVC参数注入,这里用@param绑定也同样出现上述问题)
- 解决方案是通过使用对象对参数进行封装(参考下述接口中的FunList)
(三)ajax传Map
**关键:**不是用js的map传,用js的对象生成map,使用map[key]=value的形式传
- Map传参,不能使用js自带的Map对象传参
- 需定义对象(用{}定义)
- --------------------使用js自带的Map传参---------------
- 前端发送的参数将不会携带map(表现为:如果只有map一个参数,那么传参为空,如果有其他参数,则提交除了map外的其他参数)
- --------------------使用对象进行传参------------------
- 前端能正常发送,后台如果要接收数据,需使用对象封装的map接收
-
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script language="javascript" type="text/javascript"
src="js/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="js/index.js"></script>
<title></title>
</head>
<body>
<div class="container">
<div class="row-fluid">
<button onclick="fun1()">List (traditional=false)</button>
</div>
<div class="row-fluid">
<button onclick="fun2()">List (traditional=true)</button>
</div>
<div class="row-fluid">
<button onclick="fun3()">Map (map对象)</button>
</div>
<div class="row-fluid">
<button onclick="fun4()">Map (array对象)</button>
</div>
<div class="row-fluid">
<button onclick="fun5()">List (在Controller中用List接收)</button>
</div>
<div class="row-fluid">
<button onclick="fun2()">List (在Controller中用对象接收)</button>
</div>
</div>
</body>
<script>
var ip = "http://127.0.0.1:8080";
var list = [ 1, 2, 3, 4, 5, 6 ];
var map = new Map();
map.set('1', 'hello');
map.set('2', 'world');
var mapList = {};
mapList['1'] = 'hello';
mapList['2'] = 'world';
mapList['ni'] = 'hao';
mapList[100] = 'hello2';
mapList[99] = 'world2';
//fun1(List传参)失败
function fun1() {
$.ajax({
type : 'post',
url : ip + '/list/obj',
contentType : 'application/x-www-form-urlencoded',
dataType : 'json',
async : false,
traditional : false,
data : {
idList : list,
},
success : function(result) {
},
error : function() {
},
});
}
//fun2(List传参)成功
function fun2() {
$.ajax({
type : 'post',
url : ip + '/list/obj',
contentType : 'application/x-www-form-urlencoded',
dataType : 'json',
async : false,
traditional : true,
data : {
idList : list,
},
success : function(result) {
}
});
}
//fun3(Map传参)失败
function fun3() {
$.ajax({
type : 'post',
url : ip + '/map/obj',
contentType : 'application/x-www-form-urlencoded',
dataType : 'json',
async : false,
data : {
id : '1',
map : map,
},
success : function(result) {
}
});
}
//fun4(Map传参)成功
function fun4() {
$.ajax({
type : 'post',
url : ip + '/map/obj',
contentType : 'application/x-www-form-urlencoded',
dataType : 'json',
async : false,
// traditional: true,
data : {
id : '1',
map : mapList,
},
success : function(result) {
}
});
}
//直接在Controller里声明List或Map,结果报错,接收不到,只能通过对象封装生成
function fun5() {
$.ajax({
type : 'post',
url : ip + '/list/self',
contentType : 'application/x-www-form-urlencoded',
dataType : 'json',
async : false,
traditional : true,
data : {
idList : list,
},
success : function(result) {
}
});
}
</script>
</html>
ListController
@Controller
@Slf4j
public class ListController{
public static final Gson GSON=new Gson();//Gson对象
/**
* 直接传List
* 结果:报java.lang.NoSuchMethodException错误
* @param list
*/
@PostMapping("/list/self")
@ResponseBody
public void list1(List<String> list){
log.info("list1:" +GSON.toJson(list));
}
/**
* 使用对象封装List
* 正确接收的条件:
* 1)ajax的traditional为true
* 2)后台接口用对象接收
* @param list
*/
@PostMapping("/list/obj")
@ResponseBody
public void list2(FunList funList){
log.info("list2:" +GSON.toJson(funList));
}
}
MapController
@Controller
@Slf4j
public class MapController{
public static final Gson GSON=new Gson();//Gson对象
/**
* 直接传Map
* (报错)
* @param Map
*/
@PostMapping("/map/self")
@ResponseBody
public void map1(Map<String,String> map){
log.info("map1:" +GSON.toJson(map));
}
/**
* 使用对象封装List
* (正确接收)
* @param list
*/
@PostMapping("/map/obj")
@ResponseBody
public void map2(FunMap funMap){
log.info("map2:" +GSON.toJson(funMap));
}
}
FunList和FunMap:
@Data
public class FunMap {
private Map<String,String> map;
}
@Data
public class FunList {
private List<String> list;
}