版本:Java + Springboot2.0
快速测试环境:github地址
1. Jquery版本Ajax请求的格式
代码如下:
$.ajax({
type: "get"
, url: "/test"
, data: ""
,contentType: "application/json; charset=utf-8"
, dataType: 'json'
, success: function (res) {
}
});
- type 控制请求的方式
- url 是请求的链接
- data 发送的数据
- contentType 发送数据的格式
- dataType 服务端返回数据的格式
可以看得到我们怎么发送数据,服务端怎么接收数据最直接的影响就是contentType的设置,我们下面以两种常见的ContentType为界限,来看各种类型(type:post/get等)的请求如何发送参数。
2. 默认(不写)ContentType
在jquery的ajax方法中,默认的ContentType的值为:application/x-www-form-urlencoded; charset=UTF-8 。
此格式为表单提交格式,最终提交给后台的数据为key1=value1&key2=value2的格式 。
虽然ajax的data属性值格式为:{key1:value1,key2:value2},但最后会转为key1=value1&key2=value2的格式提交到后台 ,如果ajax要和springmvc交互,key1=value1&key2=value2的格式,后台springmvc只需要定义对象或者参数就行了,框架会自动映射。
下面是一个例子:
发送的数据是data变量,ajax请求如下,注意没有写contentType
function test() {
var data = {
code : "code",
name : "name"
};
$.ajax({
type: "get"
, url: "/test"
, data: data
, dataType: 'json'
, success: function (res) {
}
});
}
我们用chrome浏览器看看到底发给后台的数据是什么,截图如下:
1.png
注意看URL,由于是GET请求,所以会把参数拼接在后面,或者看下面的红框中的参数也是同样的。
后台的接收方式如下:
@RequestMapping(value = "/test", method = RequestMethod.GET)
public void test(String code, String name) {
System.out.println(code);
System.out.println(name);
}
并且打印出来了
code
name
上面是GET方式请求的例子,那么我们再继续测试RESTFUL风格中的其他请求方式。
其中RESTFUL风格的写法如下:
- 获取:使用GET方法获取资源。GET请求从不改变资源的状态。无副作用。GET方法是幂等的。GET方法具有只读的含义。因此,你可以完美的使用缓存。
- 创建:使用POST创建新的资源。
- 更新:使用PUT更新现有资源。
- 删除:使用DELETE删除现有资源。
具体的可以参考这篇博客[译] RESTful API 设计最佳实践
2.1 POST请求 (用复杂对象接收)
发送的请求和数据如下:
可以看到我们把数据变化了下,code传入的是一个js object对象了
function test() {
var code = {
key : "11",
value : 12
};
var data = {
code : code,
name : "name"
};
$.ajax({
type: "post"
, url: "/test"
, data: data
// ,contentType: "application/json; charset=utf-8"
, dataType: 'json'
, success: function (res) {
}
});
}
看一下请求头发送的都是什么:
2.png
所以这样后台获取code就获取不到了,分析一下上面传递过去的格式,明显code是一个键值对的格式,我们用一个对象去接收。对象代码如下:
public class ViewModel {
private Map<String, Object> code;
private String name;
}
后台接收如下:
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void test(Map<String, Object> viewModel) {
System.out.println(iewModel);
}
// 打印结果:
// 值为:ViewModel{code={key=11, value=12}, name='name'}
这样可以接收到传递过去的数据,但是如果直接在参数把code写成一个Map的形式式获取不到值的:
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void test(Map<String, Object> code, String name) {
System.out.println("code为:" + code);
System.out.println("name为:" + name);
}
// 打印结果:
// code为:{}
// name为:name
原因后面继续追踪。
2.2 PUT请求 (如何获取Json字符串)
这次我们用put进行请求,并且我们想获取到的code不再是一个js对象,而是一个JSON字符串,我们需要用JSON.stringify(code)方法把一个js对象处理成字符串。
function test() {
var code = {
key : "11",
value : 12
};
var data = {
code : JSON.stringify(code),
name : "name"
};
$.ajax({
type: "put"
, url: "/test"
, data: data
, dataType: 'json'
, success: function (res) {
}
});
}
观察请求头的内容如下:
3.png可见我们以及发送一个String类型的code过去了,我们用老方式去接收,如下:
@RequestMapping(value = "/test", method = RequestMethod.PUT)
public void test(String code, String name) {
System.out.println("code为:" + code);
System.out.println("name为:" + name);
}
// 打印结果
// code为:{"key":"11","value":12}
// name为:name
拿到了JSON字符串我们在利用Gson等工具包处理成我们想要的类即可。
2.3 DELETE请求(和其他的不太一样)
我们按照以上的方式去请求,一切都和以前一样,结果居然后台code和name都获取不到。
function test() {
var data = {
code : "code"
name : "name"
};
$.ajax({
type: "delete"
, url: "/test"
, data: data
, success: function (res) {
}
});
}
很奇怪,去网上查了一下资料发现,jquery对delete处理比较独特,DELETE请求方式是基于POST请求方式,必须在表单提交中写上一个隐藏域,而且必须将name设置为_method,value属性值写上对应的请求方式。
具体写法如下,注意看与上面代码不同的地方:
function test() {
var data = {
code : "code",
name : "name"
};
// DELETE方式独有
data["_method"] = 'DELETE';
$.ajax({
// 注意改为了post
type: "post"
, url: "/test"
, data: data
, success: function (res) {
}
});
}
这样按照原来的后台,结果如下:
@RequestMapping(value = "/test", method = RequestMethod.DELETE)
public void test(String code, String name) {
System.out.println("code为:" + code);
System.out.println("name为:" + name);
}
// 打印结果:
// code为:code
// name为:name
3. ContentType 设置为 application/json; charset=UTF-8
如果springmvc的参数有@RequestBody注解(接收json字符串格式数据),则ajax请求必须将data属性值转为json字符串,不能为json对象(js对象,会自动转为key=value形式)。
然后再修改contentType的值为:application/json; charset=UTF-8,这样加了@RequestBody注解的属性才能自定映射到值。
3.1 以POST请求为例
我们发送请求的数据如下:
这其中需要注意的是
- 设置了contentTpye
- data是一个js对象,传过去必须要JSON.stringify(data),转化成json字符串才行。
function test() {
var code = {
key : "11",
value : 12
};
var data = {
code : code,
name : "name"
};
$.ajax({
type: "post"
, url: "/test"
, data: JSON.stringify(data)
,contentType: "application/json; charset=utf-8"
, success: function (res) {
}
});
}
以这样为请求方式,我们看一下发送的请求头的样子:
4.png
可以看到,发送过去的数据确确实实变成了json格式的,然后springmvc会自动调用Jackson,将json字符串转化成我们想要的格式。所以我们后头接收如下:
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void test(@RequestBody Map<String, Object> viewModel) {
System.out.println("值为:" + viewModel);
}
// 打印结果:
// 值为:{code={key=11, value=12}, name=name}
同样,如果我们想用自定义的类去接收,去定义好类,并且把json中的健和值对应上即可。
4. HTTP头 Content-Type
- 作用:contentType的作用是用来标识发送或者接收数据的MIME类型。
- 格式:type/subtype(;parameter)? type
- 样例:Content-Type:application/json;charset=GBK
- type代表主类型,比如application
- subtype代表副类型,比如json
- parameter可选,比如charset
- 其中*代表所有类型
5. 常见的contentType类型
- 主类型为text的
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式 - 以application开头的媒体格式类型:
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
END
参考
Http协议之Content-Type
Ajax发送PUT/DELETE请求时出现错误的原因及解决方案
@RequestBody, @ResponseBody 注解详解
SpringMVC中ajax传值的几种接收方式
网友评论