标签: SpringMVC
@RequestBody
Json
AJAX
在使用SpringMVC+AJAX提交数据的时候一直提交不成功,发现自己对于SpringMVC AJAX提交数据的认知完全是错误的,重新学习整理。
什么是JSON对象/字符串
JSON对象:
var jsonObj={
"loginName":"huanyan",
"name":"化烟雨",
"gender":"1",
}
这种格式的叫JSON对象而由"引号括起来的称为JSON字符串
输出数据表现形式的对比
JSON对象:
——输出出来的是一个对象,而JSON字符串输出的是字符串形式
JSON字符串/对象之间的转换
使用的是JSONAPI
API | 简介 |
---|---|
JSON.stringify() | JSON对象->JSON字符串 |
JSON.parse() | JSON字符串->JSON对象 |
SpringMVC+AJAX提交形式
我们先来说说SpringMVC 数据提交的两个注解@RequestParam
@RequestBody
对于Http协议
,在不指定Content-Type
的前提下默认为application/x-www-form-urlencoded
@RequestParam
JSON试例:
//json对象格式1
jsonobj={"user":{"departmentId": "1",//省略字段
"description": "s"}};
//json对象格式2
jsonobj={"departmentId": "1",//省略字段
"description": "s"};
//json字符串格式1
jsonStr='{"user":{"departmentId": "1",//省略字段
"description": "s"}}';
//json字符串格式2
jsonStr='{"departmentId": "1",//省略字段
"description": "s"}';
//以上格式轮流替换在控制台测试
$.ajax({
type: "GET",//get与post 轮流测试
url: "/user/test1",test1 or test2
dataType: "json",
data:jsonobj,
success: function (jsonResult) {
alert(jsonResult);
}
});
以下是controller
后台代码
@RequestMapping(value = "/test1")
public String test1(@RequestParam("user") User user, ModelMap modelMap){
return "public/message";
}
@RequestMapping(value = "/test2")
public String test2(@RequestParam("departmentId") Long id,@RequestParam("longName") String name, ModelMap modelMap){
return "public/message";
}
小结:
JSON对象:
对于JSON对象格式1
对于test1
test2
都是无效语法错误:HTTP400
,而只有JSON对象格式2
对于test2
可以接收数据。
JSON字符串:
对于JSON字符串格式1
JSON字符串格式2
对于test1
test2
都是无效语法错误:HTTP400
。
@RequestBody
对于测试@RequestBody
需要指定Content-Type
为application/json
,并且AJAX需要提 交
JSON字符串形式 的数据
。
这里就不多做测试了!懒~
方式一: 数据包装类的形式
$.ajax({
type: "POST",
url: "/user/add",
contentType: "application/json",
dataType: "json",
data:JSON.stringify({
"user":{
"departmentId":"1",
"loginName":"s"
},
"roles":[
{
"id":1
},
{
"id":2
}
]
}),
success: function (jsonResult) {
alert(jsonResult);
}
});
以下是controller
后台代码
@RequestMapping(value = "/add",method = RequestMethod.POST)
public String add(@RequestBody UserDto userDto, ModelMap modelMap){
return "public/message";
}
以下是包装类
后台代码
public class UserDto {
private User user;
private List<Role> roles;
//以下get/set
}
方式二: 使用Map<String,Object>的方式
AJAX提交与方式一致
以下是controller
后台代码
@RequestMapping(value = "/add2",method = RequestMethod.POST)
public String add2(@RequestBody Map<String,Object> data, ModelMap modelMap) throws Exception {
User user= JsonXMLUtils.map2obj((Map<String,Object>) data.get("user"),User.class); //使用工具类转为对象
List<Role> roles=JsonXMLUtils.map2list(data.get("roles"),Role.class);使用工具类转为集合对象
return "public/message";
}
以下是工具类 JsonXMLUtils
后台代码
package com.oa.until;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import java.util.List;
import java.util.Map;
public class JsonXMLUtils {
/**
* 对象->JSON字符串
* @param obj
* @return
* @throws Exception
*/
public static String obj2json(Object obj) throws Exception {
return JSON.toJSONString(obj);
}
/**
* json字符串->对象
* @param jsonStr
* @param clazz
* @param <T>
* @return
* @throws Exception
*/
public static <T> T json2obj(String jsonStr, Class<T> clazz) throws Exception {
return JSON.parseObject(jsonStr, clazz);
}
/**
* JSON字符串->map
* @param jsonStr
* @param <T>
* @return
* @throws Exception
*/
public static <T> Map<String, Object> json2map(String jsonStr) throws Exception {
return JSON.parseObject(jsonStr, Map.class);
}
/**
* map数据参数->对象
* @param map
* @param clazz
* @param <T>
* @return
* @throws Exception
*/
public static <T> T map2obj(Map<?, ?> map, Class<T> clazz) throws Exception {
return JSON.parseObject(JSON.toJSONString(map), clazz);
}
/**
* map数组行参数->对象集合
* @param object
* @param clazz
* @param <T>
* @return
* @throws Exception
*/
public static <T> List<T> map2list(Object object, Class<T> clazz) throws Exception {
return JSONArray.parseArray(JSON.toJSONString(object),clazz);
}
}
方式三: bean对象接收形式
这种形式与包装类的JSON字符串形式
是差别的。注意JSON字符串格式
$.ajax({
type: "POST",
url: "/user/add1",
contentType: "application/json",
dataType: "json",
data:JSON.stringify({
"departmentId":"1",
"loginName":"s",
"roles":[
{
"id":1
},
{
"id":2
}
]
}),
success: function (jsonResult) {
alert(jsonResult);
}
});
以下是controller
后台代码
@RequestMapping(value = "/add1",method = RequestMethod.POST)
public String add1(@RequestBody User user, ModelMap modelMap){
return "public/message";
}
什么时候使用 @RequestParam
@RequestBody
?
请求提交方式:
GET:会将参数以url?KEY=VALUE&KEY=VALUE的形式请求到服务器。
POST:
-
Content-Type
为默认x-www-form-urlencoded
时
在AJAX请求时会将参数转为?KEY=VALUE&....的参数形式封装到HTTP BODY请求到服务器,而数据不会显示到URL上。 -
Content-Type
指定为application/json
时
使用@RequestBody
请求方式必须为POST,不然会报HTTP 400
错误
GET/POST形式下:
@RequestParam
:可以处理Content-Type
的类型
application/x-www-form-urlencoded
multipart/form-data
@RequestBody
:可以处理Content-Type
的类型
application/json
application/xml
注:
在jsp中使用ajax提交时出现了下面的问题: 415 (Unsupported Media Type), 可能出现的原因如下:
- dataParam 格式错误,不符合json字符串规范
- dataParam 参数不能绑定到控制器方法的参数上面,不是一一对应
- 没有在ajax提交时设置contentType
contentType指的是前台传递到后台的格式,dataType指的是由后台传到前台的格式- jackson的jar包不对或者不全:
不应该使用org.codehaus.jackson下面的jackson.jar, 应该使用com.fasterxml.jackson.core下面的>jackson->core和jackson-databind 的jar包- 加上<mvc annotation-driven>
6.springMVC配置文件没配好
参考文档-3
参考文档:
SpringMVC接受JSON参数详解及常见错误总结
@RequestBody, @ResponseBody 注解详解(转)
@requestBody @responseBody配置要点