標簽: 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配置要點