@RequestBody注解
Spring中@RequestBody注解,用于读取Request请求的body数据,并根据内容类型(Content Type)确定使用哪个HttpMessageConverter
进行解析。
@RequestBody默认提供:StringHttpMessageConverter
,ByteArrayHttpMessageConverter
,
SourceHttpMessageConverter
,AllEncompassingFormHttpMessageConverter
,其中AllEncompassingFormHttpMessageConverter
继承自FormHttpMessageConverter
处理表单提交相关。具体查看org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.java
1
2
3
4
5
6
7
8
9
10
11
|
public RequestMappingHandlerAdapter() {
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
stringHttpMessageConverter.setWriteAcceptCharset(false); // see SPR-7316
//默认的4种消息转换器
this.messageConverters = new ArrayList<HttpMessageConverter<?>>(4);
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(stringHttpMessageConverter);
this.messageConverters.add(new SourceHttpMessageConverter<Source>());
// 表单消息转换类
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
}
|
AllEncompassingFormHttpMessageConverter中根据classpath中的jar提供了json及xml相关的转换类。
AllEncompassingFormHttpMessageConverter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter {
private static final boolean jaxb2Present =
ClassUtils.isPresent("javax.xml.bind.Binder",
AllEncompassingFormHttpMessageConverter.class.getClassLoader());
private static final boolean jackson2Present =
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
AllEncompassingFormHttpMessageConverter.class.getClassLoader()) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
AllEncompassingFormHttpMessageConverter.class.getClassLoader());
private static final boolean jackson2XmlPresent =
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper",
AllEncompassingFormHttpMessageConverter.class.getClassLoader());
private static final boolean gsonPresent =
ClassUtils.isPresent("com.google.gson.Gson",
AllEncompassingFormHttpMessageConverter.class.getClassLoader());
public AllEncompassingFormHttpMessageConverter() {
addPartConverter(new SourceHttpMessageConverter<Source>());
if (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
addPartConverter(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
addPartConverter(new GsonHttpMessageConverter());
}
if (jackson2XmlPresent) {
addPartConverter(new MappingJackson2XmlHttpMessageConverter());
}
}
}
|
常用表提交内容类型(Content-Type)
提交的数据按照 key1=val1&key2=val2 的方式进行编码,大多数的数据提交为这种方式,包括JQuery的ajax等。在Spring中可以使用@RequestParam
,@RequestBody
,@ModelAttribute
处理。
1
2
3
4
|
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&content=test |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
var data = {
name : 'binbean'
};
$.ajax('/test', {
method:'POST',
// 将数据编码为表单模式
contentType:'application/x-www-form-urlencoded; charset=UTF-8',
// 数据必须为JS对象,非字符串
data : data,
success : function(datas) {
console.log(datas)
}
})
|
spring中对应的处理方式为
方法1,使用@RequestParam
1
2
3
4
5
6
7
8
|
@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity<String> test(
@RequestParam("param1") String param1,
@RequestParam("param2") String param2, @RequestParam("param3") String param3) {
...
...
return new ResponseEntity<String>(HttpStatus.OK);
}
|
方法2,使用@RequestBody
,MultiValueMap接收提交数据
1
2
3
4
5
6
|
@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity<String> test(@RequestBody MultiValueMap<String, String> params) {
...
...
return new ResponseEntity<String>(HttpStatus.OK);
}
|
方法3,使用@ModelAttribute
,对象(User)接收提交的数据
1
2
3
4
5
6
7
8
|
@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity<String> test(@ModelAttribute("user") User user)
{ ...... }
@ModelAttribute("user")
public User getUser() {
return new User();
}
|
常见的上传文件表单提交方式。可使用@RequestParam
注解处理。@RequestBody
不能处理这种类型的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@RequestMapping("/fileUpload")
public String fileUpload(@RequestParam("file") MultipartFile file) {
// 判断文件是否为空
if (!file.isEmpty()) {
try {
// 文件保存路径
String filePath = "/upload/" + file.getOriginalFilename();
// 转存文件
file.transferTo(new File(filePath));
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
3 application/json
以json格式提交数据。可以使用@RequestParam
,@RequestBody
处理接收数据。
1
2
3
4
5
6
7
8
9
10
11
12
|
var data = {
name : 'binbean'
};
$.ajax('/test', {
method:'POST',
contentType:'application/json;charset=utf-8', charset=UTF-8',
// 数据必须转换为字符串
data : JSON.stringify(data),
success : function(datas) {
console.log(datas)
}
})
|