本文使用postman来测试springMVC的@RequestParam
和@RequestBody
注解的区别。
测试数据为:
@RequestBody
@RequestMapping("test")
@ResponseBody
public User test(@RequestBody User user) {
return user;
}
@RequestBody
的作用:
@RequestBody
可以接收POST
请求content-type
为application/json
的参数,消息体中的参数为json格式,springmvc会使用MappingJackson2HttpMessageConverter
将json格式的参数转换为java对象,MappingJackson2HttpMessageConverter
默认支持的格式为content-type:application/json
。
说明:测试@RequestBody
时,发送的都是POST
请求
1.测试content-type:application/json
测试结果为:
2.测试content-type:application/x-www-form-urlencoded
测试结果为:
后台出现了错误,查看控制台,错误信息为:
2020-07-01 18:02:24.358 WARN 4060 --- [io-8081-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]
原因是MappingJackson2HttpMessageConverter
默认只支持content-type:application/json
。
手动配置MappingJackson2HttpMessageConverter
的supportedMediaTypes
属性,增加对application/x-www-form-urlencoded;charset=UTF-8
的支持,然后继续测试。
@Bean
public HttpMessageConverters jsonHttpMessageConverters() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
converter.setSupportedMediaTypes(supportedMediaTypes);
return new HttpMessageConverters(converter);
}
后台错误信息为:
是因为json格式不正确,content-type:application/x-www-form-urlencoded
发送的http请求参数是键值对的格式,如下图:
@RequestParam
@RequestParam
的作用:
@RequestParam
可以接收POST
请求content-type:application/x-www-form-urlencoded
和GET
请求url的querystring里的参数。不能使用封装的对象接收参数,只能将参数单独接收,但可以将参数用一个map接收
@RequestMapping("test")
@ResponseBody
public User test(@RequestParam(required = false) User user) {
return user;
}
1.测试content-type:application/json
user为null
2.测试content-type:application/x-www-form-urlencoded
user为null
以上可以看出,@RequestParam
注解无法将参数与User对象进行绑定,我们将后台代码改为如下后再测试:
@RequestMapping("test")
@ResponseBody
public User test(@RequestParam(required = false) String userName,@RequestParam(required = false) String password) {
User user = new User();
user.setUserName(userName);
user.setPassword(password);
return user;
}
测试content-type:application/json
**
由于content-type:application/json
为json格式,不是键值对的格式的参数,使用@RequestParam
是无法接收的
测试content-type:application/x-www-form-urlencoded
**
1.使用post请求:
2.使用get请求:
使用get请求时,@RequestParam
并没有接收到参数,这是因为postman将参数放在了消息体中,当是get类型的请求时,@RequestParam
会解析url的querystring里的参数,所以在这里后台的userName和password为null。
从这里也可以看出来,其实http的get请求,参数也可以放在消息体中,只不过浏览器对于get请求,是将参数拼到url后面。除了浏览器,在其他地方(比如httpClient)使用http将参数放到消息体中也是没问题的。如果在浏览器使用ajax或form表单测试get请求时,后台就能够接收到。在controller的带@RequestMapping
的方法中如果是简单类型的参数(如String,Integer等,由spring的BeanUtils#isSimpleProperty
判断),参数会默认使用@RequestParam
。