Ajax给SpringMVC传值遇到400或者415,这是由于在后台服务端定义的参数与传送的格式对应不上引起的。
400 请求出错
由于语法格式有误,服务器无法理解此请求。不作修改,客户程序就无法重复此请求。
415
介质类型不受支持 — 服务器拒绝服务请求,因为不支持请求实体的格式。
检查 data 吧,看看提交到后台的数据是否合法!
我们之前已经在之前的文章中解决了其中一种情况:
今天又遇到了这个问题,所以很有必要梳理一下,Ajax给java后端传值,SpringMVC接收传值的用法。
contentType不设置或者application/x-www-form-urlencoded模式
格式
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是后台执行完毕后的回调函数。
示例用法
jsp页面
$.ajax({
type : 'post', //可选get
url : '/chip/saveMulti', //这里是接收数据的程序
data: 'rsid='+rsid+'&name='+name, //传给后台的数据,多个参数用&连接
dataType: 'Json', //服务器返回的数据类型 可选XML ,Json jsonp script html text等
success: function(data) {
if(data.code == 0){
alert("更新成功.");
}
if(data.code == -1){
alert("更新失败!!!");
}
},
error: function() {
alert("请求失败!!!");
}
});
或者使用
$.ajax({
type : 'post', //可选get
url : '/chip/saveMulti', //这里是接收数据的程序
data: {"rsId":rsId,"name":name}, //传给后台的数据
dataType: 'Json', //服务器返回的数据类型 可选XML ,Json jsonp script html text等
success: function(data) {
if(data.code == 0){
alert("更新成功.");
}
if(data.code == -1){
alert("更新失败!!!");
}
},
error: function() {
alert("请求失败!!!");
}
});
因为不设置contentType的情况会默认使用application/x-www-form-urlencoded模式(表单提交模式),所以这里加上contentType="application/x-www-form-urlencoded"。效果是一样的。
后端路由Controller中接收参数代码如下:
@RequestMapping("/chip/saveMulti")
@ResponseBody
public JSONResult fixUserProduct(@RequestParam String rsid, @RequestParam String name){
if(StringUtils.isBlank(rsid) || StringUtils.isBlank(name)){
return JSONResult.error("参数为空");
}
return JSONResult.success("success");
}
contentType设置为application/json模式
格式
$.ajax({
url: "",
type: "",
dataType: "",
contentType:"application/json",
data: {},
success: function () { }
});
示例用法
jsp页面
$.ajax({
type : "POST",
url : "/shipment/save",
contentType : "application/json",
data : JSON.stringify(data),
success : function(result) {
console.log(result);
if (!result.code) {
$('#shipment').formSet(data);
location.href = '/shipment'
}else{
alert(result.msg);
}
},
error : function(result) {
alert("出错了,请稍后重试");
}
});
后端路由Controller中可以使用实体接收
如下Shipment是我们的一个实体,则接收代码如下:
@RequestMapping("/shipment/save")
@ResponseBody
public JSONResult saveShipment(@RequestBody Shipment shipment) {
//执行保存操作
//int result = shipmentService.upsertShipment(shipment);
return result > 0 ? JSONResult.success(shipment) : JSONResult
.error("保存失败!");
}
也可以使用JsonObject来接收再赋值给实体:
@RequestMapping("/shipment/save")
@ResponseBody
public JSONResult saveShipment(@RequestBody JsonObject shipmentJson) {
Shipment shipment=new Shipment();
shipment.setName(shipmentJson.get("name"));
//执行保存操作
//int result = shipmentService.upsertShipment(shipment);
return result > 0 ? JSONResult.success(shipment) : JSONResult
.error("保存失败!");
}
因为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字符串作为发送数据,这样可读性更好,并且对于复杂的接收数据类型,也能起到很好的匹配。
更多用法
jsp页面:
<script type="text/javascript">
function allhtml() {
document.getElementById("showdiv").innerHTML ="";
$.ajax({
type: 'post', //可选get
url: 'showcontent', //这里是接收数据的程序
data: 'data=2', //传给后台的数据,多个参数用&连接
dataType: 'html', //服务器返回的数据类型 可选XML ,Json jsonp script html text等
success: function(msg) {
//这里是ajax提交成功后,程序返回的数据处理函数。msg是返回的数据,数据类型在dataType参数里定义!
document.getElementById("showdiv").innerHTML = msg;
//$("#duoduo").innerHTML = msg;
},
error: function() {
alert('对不起失败了');
}
})
}
function jsonhtml() {
var successUUID = function(data){
if(data.data.detailOk=='ok'){
document.getElementById("showdiv").innerHTML =data.data.content;
}
};
$.ajax({
dataType: "json",
url: "showcontentjson",
success: successUUID,
cache:false
});
}
</script>
JSONResult.java
package com.test.web.message.response;
/**
* JSONResult
* 标准化的JSON响应
*
* <pre>
* {@link JSONResult#success(Object)}
* {@link JSONResult#error(String)}
* </pre>
*
*
*/
public class JSONResult {
/**
* 成功的代码
*/
public static final int CODE_SUCCESS = 0;
/**
* 错误的代码,可根据错误类型进行详细分类
*/
public static final int CODE_ERROR = -1;
/**
* 空白的成功响应
*/
public static final JSONResult RESULT_SUCCESS_NO_DATA = new JSONResult(CODE_SUCCESS, null, null);
private int code;
private String msg;
private Object data;
/**
* 创建一个成功的响应
*
* @param data
* @return
*/
public static JSONResult success(Object data) {
return new JSONResult(CODE_SUCCESS, null, data);
}
/**
* 创建一个错误的响应
*
* @param msg
* @return
*/
public static JSONResult error(String msg) {
return new JSONResult(CODE_ERROR, msg, null);
}
/**
* @param code
* @param msg
* @param data
*/
public JSONResult(int code, String msg, Object data) {
this.code = code;
this.setMsg(msg);
this.data = data;
}
public int getCode() {
return code;
}
public JSONResult setCode(int code) {
this.code = code;
return this;
}
public Object getData() {
return data;
}
public JSONResult setData(Object data) {
this.data = data;
return this;
}
public String getMsg() {
return msg;
}
public JSONResult setMsg(String msg) {
this.msg = msg;
return this;
}
}
IndexController.java
package com.test.web.controller;
import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.test.web.message.response.JSONResult;
/**
* IndexController
*
*
*/
@Controller
public class IndexController {
private String mongodb;
public void setMongodb(String mongodb) {
this.mongodb = mongodb;
}
@RequestMapping("/showcontentjson")
@ResponseBody
public Object contentjson() {
JSONObject json = new JSONObject();
json.put("content", "局部刷新返回json后拼凑html");
String detailOk = "ok";
json.put("detailOk", detailOk);
return JSONResult.success(json);
}
@RequestMapping("/showcontent")
public String content(Model model)
throws IOException {
model.addAttribute("content", "局部刷新返回整个页面");
return "/content";
}
@RequestMapping(value={"/","/index"})
public String index(Model model)
throws IOException {
System.out.println(mongodb);
return "/home";
}
}