目录

解决关于ssm框架前端ajax请求,后端返回数据正常,而前端接收到的数据为undefined的情况

解决:关于ssm框架前端ajax请求,后端返回数据正常,而前端接收到的数据为undefined的情况

记录一个菜鸟用周末两天时间爬出的一个坑,我xx真的服了。

以下描述内容不够严谨,过程就是这么个过程,细节不讲。

内容用于个人学习记录和交流,如有问题还请批评指正。


问题描述:

最近学习的ssm框架,其中比较重要的功能就是默认集成了jackson,当使用@ResponseBody注解标注的controller方法,该方法的返回值不解析成地址,交给请求体发送回前端,如果返回值是对象,那么jackson会自动将对象转换成json字符串。

这个坑是如何踩到的?

在前端通过ajax向服务器发送请求,过程完美且优雅,服务器返回内容也在控制台打印出来

https://i-blog.csdnimg.cn/blog_migrate/afdd85393ca31b2b3c81946890f5516e.png#pic_center

从上方日志和输出结果看的出来,从服务器接收到请求,然后查询数据库返回了六条数据,得到的数据打印在控制台发现是没问题的。

https://i-blog.csdnimg.cn/blog_migrate/e9755266482c9517d7106861e93a6306.png#pic_center

但是,将数据渲染到下拉列表的option标签中时,显示的值为 undefined 未定义。

https://i-blog.csdnimg.cn/blog_migrate/dd7c84f08d82a1bb432d0edf89b8885d.png#pic_center


原因分析:

从上方的描述和图片可以看到,请求和数据都是没有问题的,服务器接收到了请求,也查询到了正确的数据,控制器也将正确的数据返回给了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

https://i-blog.csdnimg.cn/blog_migrate/d8068f2bd84b6b6c5eb2a587fac8a2d0.png#pic_center

这时候我就没有头绪了,上网搜索了很多资料,人家出现的情况和我相同可是解决不了我的问题。

还有很多我就不罗列了。

那么问题出现在哪,我就想不明白。一度迷失在百度中。


解决方案:

直到最后才想到,是不是我的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;
    }

控制台输出的内容

从数据库查询到的数据:

https://i-blog.csdnimg.cn/blog_migrate/10d20e38b0cddbeb52d24aebe9485b55.png#pic_center

转换成json之后的字符串:

https://i-blog.csdnimg.cn/blog_migrate/89497f7e09d734c9ed640bed9610d480.png#pic_center

然后,我到前端观察数据渲染的情况。

发现,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>

渲染后的下拉列表

https://i-blog.csdnimg.cn/blog_migrate/5d03f52c2bb23902c34e11ed2157ef19.png#pic_center

难受,卡了我老长时间了。


总结:

在以后ajax请求后台并获取后台数据时,

  1. 在控制台输出返回给前端的数据,是否正确
  2. 到前端后,将数据根据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]);
			}
		}                                       
	}
})
  1. 观察一下弹出的结果,在合理使用返回的数据。

补充解决一个问题:

前端表单提交,后端采用 @RequestBody 实体类接受前端参数时 也是jackson自动转换,那么知道该怎么做了吧。

input标签的name属性值,对应实体类的属性名,且属性名要小写,后端才会自动封装成实体类的对象!