springMVC学了也有一个星期了,之前一直是用ModelAndView传jsp页面给前端,今天学习前后端异步JSON通信的时候遇到一些坑,记下来免得自己忘了
修改springMVC.xml配置
需要在springMVC.xml配置文档中修改<mvc:annotation-driven>注解,增加StringHttpMessageConverter组件的配置,不然Controller无法解析前端的JSON数据
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/plain;charset=UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
配置jar包
首先在maven的pom文件中舔加Jackson的jar包依赖,用于spring将JSON解析为pojo对象,由于使用的spring是4.1.3版本的,因此必须用2.x的Jackson:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
</dependency>
1. 前端传送JSON对象给后端
通过ajax异步传送JSON数据给后端,需要注意的是传输method必须为post,且必须指定dataType和contentType,否则springMVC无法识别数据类型,会造成415报错
前端以JSON字符串的形式将id和name两个参数发送给后端,需要注意的是,由于已经指定了dataType,因此ajax传输成功的回调函数中获得 result直接就是JSON对象,无需调用parse方法解析JSON字符串:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" charset="UTF-8" content="text/html; charset=utf-8">
<title>JSON</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<h1>以JSON方式提交Category数据</h1><br>
<form>
id:<input type="text" id="id" value="12"><br>
名称:<input type="text" id="name" value="不知道是哪个类别"><br>
<input type="button" id="sender" value="提交">
</form>
<script>
$("#sender").click(function () {
var id = $("#id").val();
var name = $("#name").val();
var category = {"id":id, "name":name};
var jsonData = JSON.stringify(category);
//前端传给后端的数据必须是JSON字符串
var page="submitCategory";
$.ajax({
type:"post", url:page, data:jsonData, dataType:"json", contentType : "application/json;charset=UTF-8",
success: function(result){
// var json = JSON.parse(result);
alert(result.OK);
//由于指定了dataType,因此前端接收到的数据直接就是JSON对象,无需再parse
}
});
});
</script>
</body>
</html>
后端接收到数据并打印,特别注意的是需要有@RequestBody注解表示直接从前端的请求体中解析数据,并且需要有@ResponseBody注解,这时将不启用视图解析器,而是直接向前端返回数据体(一般是JSON或者XML数据)
@ResponseBody
@RequestMapping("/submitCategory")
public String submitCategory(@RequestBody Category category){
System.out.println("已接收到JSON对象,并转换为Category:"+category);
JSONObject jsonObject = new JSONObject();
jsonObject.put("OK", "OK");
return jsonObject.toJSONString();
//将JSON对象转换为JSON字符串再传给前端,需要有@ResponseBody注解
}
2. 后端传送JSON对象给前端
前端发起异步请求:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" charset="UTF-8" content="text/html; charset=utf-8">
<title>JSON</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<input type="button" id="getter" value="获得一个category">
<script>
$("#getter").click(function () {
$.ajax({
type:"post", url:"getOneCategory",
success:function(result){
var json = JSON.parse(result);
//因为没有指定dataType,因此后端传来的是JSON字符串,需要经过转换才能得到JSON对象
alert(json.category.name);
//获取JSON对象中category的name属性
}
})
})
</script>
</body>
</html>
特别注意如果在ajax请求中不指定dataType的话,返回的数据是JSON字符串,这时候就需要调用JSON.parse()方法解析成JSON对象才能使用其中的数据
后端发送数据:
@ResponseBody
@RequestMapping("getOneCategory")
public String getOneCategory(){
Category category = categoryService.get(3);
//通过service层进行DAO操作,获取category数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("category", JSONObject.toJSON(category));
return jsonObject.toJSONString();
//将JSON对象转换为JSON字符串再传给前端,需要有@ResponseBody注解
}
后端发送的一定是JSON字符串
3. 后端传送JSON对象数组给前端
前端发起异步请求:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" charset="UTF-8" content="text/html; charset=utf-8">
<title>JSON</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<input type="button" id="getMany" value="获得很多个category">
<div id="msg">将这些category打印出来</div>
<script>
$("#getMany").click(function () {
$.ajax({
type:"post", url:"getManyCategory",
success:function(result){
$("#msg").html("将这些category打印出来");
var json = JSON.parse(result);
//因为没有指定dataType,因此后端传来的是JSON对象数组字符串,需要经过转换才能得到JSON对象数组
for(i in json){
var old = $("#msg").html();
$("#msg").html(old+"<br>"+json[i].id+"---"+json[i].name);
}
//通过JSON对象数组下标,将数组中的category元素打印出来
}
})
})
</script>
</body>
</html>
后端查询数据并发送JSON数组字符串:
@ResponseBody
@RequestMapping("getManyCategory")
public String getManyCategory(){
List<Category> categories = categoryService.list();
//获取多个category对象,保存为List
return JSONObject.toJSON(categories).toString();
//返回JSON字符串
}
注意事项跟第二个例子一样,也需要将传回来的JSON字符串解析为JSON数组,然后才能获取其中的数据
总之其中需要特别注意的就是ajax请求中的dataType和contentType,以及Controller的几个注解