解决关于ssm框架前端ajax请求,后端返回数据正常,而前端接收到的数据为undefined的情况
解决:关于ssm框架前端ajax请求,后端返回数据正常,而前端接收到的数据为undefined的情况
记录一个菜鸟用周末两天时间爬出的一个坑,我xx真的服了。
以下描述内容不够严谨,过程就是这么个过程,细节不讲。
内容用于个人学习记录和交流,如有问题还请批评指正。
问题描述:
最近学习的ssm框架,其中比较重要的功能就是默认集成了jackson,当使用@ResponseBody注解标注的controller方法,该方法的返回值不解析成地址,交给请求体发送回前端,如果返回值是对象,那么jackson会自动将对象转换成json字符串。
这个坑是如何踩到的?
在前端通过ajax向服务器发送请求,过程完美且优雅,服务器返回内容也在控制台打印出来
从上方日志和输出结果看的出来,从服务器接收到请求,然后查询数据库返回了六条数据,得到的数据打印在控制台发现是没问题的。
但是,将数据渲染到下拉列表的option标签中时,显示的值为 undefined 未定义。
原因分析:
从上方的描述和图片可以看到,请求和数据都是没有问题的,服务器接收到了请求,也查询到了正确的数据,控制器也将正确的数据返回给了ajax,ajax也调用了success回调函数,回调函数也执行了循环来渲染下拉列表。
这其中只有
`data[i].iId`
和
`data[i].iName`
显示的数据是不正确的, 是未定义的。说明根本没有这两个属性。
可是通过for循环渲染的数据的长度还是正确的,即六条。 说明data是没有问题的。
那么问题就出现在这个属性名上。
.iId 和 .iName
回头查看实体类和控制器
实体类:
public class Project {
private int iId;
private String iName;
//getter and stter
}
控制器:
@GetMapping(value = "/getAll", produces = "application/json;charset=UTF-8")
@ResponseBody
public List<Institution> getAll() {
//service调用dao接口,mybatis获取所有的数据
return institutionService.getAll();
}
发现属性名也与后端的实体类的属性对应上了。况且控制台打印的输出结果中的属性名也是能对应上的的,即 iId 和 iName
这时候我就没有头绪了,上网搜索了很多资料,人家出现的情况和我相同可是解决不了我的问题。
还有很多我就不罗列了。
那么问题出现在哪,我就想不明白。一度迷失在百度中。
解决方案:
直到最后才想到,是不是我的jackson有问题,或者数据在传输过程中被外星人掳走了?
然后到前端就变成未定义了。
那么我就自己手动将对象转换成json字符串,然后控制器返回String,将json字符串返回给ajax。
改变后的控制器:
@GetMapping(value = "/getAll",produces = "application/json;charset=UTF-8")
@ResponseBody
public String getAll(){
List<Institution> all = institutionService.getAll();
System.out.println(all);//查询到的所有对象集合输出到控制台,发现数据没有问题
ObjectMapper mapper = new ObjectMapper();//jackson的映射器
try {
String s = mapper.writeValueAsString(all);//将查询到的所有对象转换成json字符串
System.out.println(s); //输出到控制台
return s;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
控制台输出的内容
从数据库查询到的数据:
转换成json之后的字符串:
然后,我到前端观察数据渲染的情况。
发现,xx的还是一个x样。手动【笑脸】。
细心的兄弟到现在一定发现了问题在哪,
观察上方两条数据
jackson映射出来的json字符串的属性值全是小写的!!!
发现问题在哪就好办了,回到前端将属性名修改为jackson返回的json字符串中的属性名。 前端ajax代码
<script>
$.ajax({
url:"institution/getAll",
contentType: "application/json;charset=utf8",
type:"get",
dataType: "json",
success:function (data) {
var select = $("[name='pIId']");
for (var i = 0 ; i < data.length;i++){
var str = "<option value='"+data[i].iid+"'>"+data[i].iname+"</option>";
var op = $(str);
select.append(op);
}
}
})
</script>
渲染后的下拉列表
难受,卡了我老长时间了。
总结:
在以后ajax请求后台并获取后台数据时,
- 在控制台输出返回给前端的数据,是否正确
- 到前端后,将数据根据json格式循环输出一下,此循环不使用 .属性名 的方式输出结果,通过索引方式输出,并且要把属性名输出出来,
$.ajax({
url:"",
contentType: "application/json;charset=utf8",
type:"get",
dataType: "json",
success:function (data) {
for(var i=0;i<data.length;i++){
for(var key in data[i]){
alert(key+':'+data[i][key]);
}
}
}
})
- 观察一下弹出的结果,在合理使用返回的数据。
补充解决一个问题:
前端表单提交,后端采用 @RequestBody 实体类接受前端参数时 也是jackson自动转换,那么知道该怎么做了吧。
input标签的name属性值,对应实体类的属性名,且属性名要小写,后端才会自动封装成实体类的对象!