Ajax給SpringMVC傳值遇到400或者415,這是由於在後臺服務端定義的參數與傳送的格式對應不上引起的。
格式
Ajax給java後端傳值我們一般使用如下:
$.ajax({
url: "",
type: "",
dataType: "",
data: {},
success: function () { }
});
url對應後臺路由的鏈接。get方式中 url後面可以跟拼接的參數如 /shipment/save?id=123&name=joe
type可以是post或者get。
dataType表示返回值類型,不必須 ,一般是json。
data則是我們傳到後臺的參數。
success是後臺執行完畢後的回調函數。
第一種:contentType不設置或者application/x-www-form-urlencoded模式
示例:data參數爲簡單key-value參數,後臺可用實體對象接收。
js代碼:$.ajax({
type : "POST",
url : rootHouse + "/crm/crmElebias/getelebiasCost",
contentType : "application/x-www-form-urlencoded;charset=utf-8",
data : {
'beginTime' : firstDayOfYear,
'endTime' : endDayOfYear,
},
success : function(result) {
},
error : function(msg) {
}
});
後臺controller第一種接受方式(實體對象):
@RequiresPermissions("crm:crmElebias:view")
@RequestMapping(value = "getelebiasCost")
@ResponseBody
public List<CrmElebias> getelebiasCost(CrmElebias crmElebias) {
return crmElebiasService.findList(crmElebias);
}
後臺controller第兒種接受方式(字符串參數):
@RequiresPermissions("crm:crmElebias:view")
@RequestMapping(value = "getelebiasCost")
@ResponseBody
public List<CrmElebias> getelebiasCost(@RequestParam String beginTime,@RequestParam String endTime) {
return crmElebiasService.findList(crmElebias);
}
不設置contentType的情況會默認使用application/x-www-form-urlencoded模式(表單提交模式),
在表單模式中,傳遞的參數data:{'beginTime' : firstDayOfYear,'endTime' : endDayOfYear,}會自動轉換成
參數拼接格式如下:beginTime=firstDayOfYear&endTime=endDayOfYear;
示例:data參數含數組參數,後臺不能用實體對象接收,數組無法被解析爲key-value形式的數據。
js:
var pointCodes= new Array(); //定義一數組
pointCodes=$('#pointCodes').val().trim().split(',');
$.ajax({
url:'/primer/bind-primer',
type:"POST",
data:{"pointCodes":pointCodes,"id":$('#primerId').val()},
success:function(res){
alert('成功');},
error:function(){
alert('服務器忙,請稍後再試'); }
});
後臺controller接受參數:
@RequestMapping("/bind-primer")
@ResponseBody
public AjaxResult bindPrimer(@RequestParam(value = "pointCodes[]") String[] pointCodes,@RequestParam String id) {
return AjaxResult.resultSuccess(primerService.bindPrimer(pointCodes, id));
}
SpringMVC傳遞一維數組:傳遞數組類型時,需要在@requestParam()中添加value。
也就是@RequestParam(value = "pointCodes[]") String[] pointCodes
這裏的pointCodes與 jsp中傳值時的key命名一致。
第二種:contentType設置爲application/json模式
data爲複雜參數,可用實體對象接收
js:
$.ajax({
type:'post',
url:'${ctx}/cost/costMwh/searchlist',
data:JSON.stringify({
companyCode:"company01",
unitId_in:["3","4"],
type_in:["3","4"],
}),
dataType:'json',
contentType:'application/json;charset=utf-8',
success:function(data){
console.log(data);
}
})
後臺controller接受方式(實體對象):
@RequiresPermissions("cost:costMwh:view")
@RequestMapping(value = "searchlist")
@ResponseBody
public List<CostMwh> searchlist(@RequestBody CostMwh costMwh) {
String[] aStrings=costMwh.getUnitId_in();
return costMwhService.findList(costMwh);
}
後臺controller接受方式(JsonObject 對象來接收再賦值給實體):
@RequiresPermissions("cost:costMwh:view")
@RequestMapping(value = "searchlist")
@ResponseBody
public List<CostMwh> searchlist(@RequestBody JsonObject shipmentJson) {
Shipment shipment=new Shipment();
shipment.setName(shipmentJson.get("name"));
//int result = shipmentService.upsertShipment(shipment);
}
因爲jQuery的ajax會默認把data:{"id":xxx,"name":xxx}這樣格式的數據拼接成id=xxx&name=xxx這種以表單數據格式提交的字符串,所以application/json需要與JSON.stringify配合使用。否則會報400或者415類型不匹配。
總結:
1.不指定contentType的話,默認都是application/x-www-form-urlencoded方式發送。此時即便發送的是json格式的數據,默認情況下,jquery的ajax也會把json轉爲查詢字符串的形式(可以通過設置processData爲true或false修改),以FormData的形式發送出去。
2.如果只接收幾個簡單參數可以使用表單模式,複雜結構建議使用json模式。
3.指定contentType爲'application/json'時候,發送的數據必須是符合json規範的字符串。通常,使用 JSON.stringify(jsondata)有較好的可讀性,可以獲得一個json字符串。當然,不是必須的。使用拼接的字符串,只要是符合json規範的,也是可以發送的。
比如:
data: JSON.stringify({ 'foo': 'foovalue', 'bar': 'barvalue' })
和
data: "{ 'foo': 'foovalue', 'bar': 'barvalue' }"
效果一樣。
4.如果contentType爲'application/json'時,發送的data不是符合json規範的字符串,則會出錯。
5.如果contentType爲'application/json'時,發送的data符合json規範的字符串,但後端接收參數中不是實體或jsonObject也會出錯。
6.通常情況下,儘量指定contentType爲'application/json',並且發送json字符串作爲發送數據,這樣可讀性更好,並且對於複雜的接收數據類型,也能起到很好的匹配。